from rest_framework import viewsets, status
from rest_framework.decorators import action, api_view, permission_classes
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
from rest_framework.views import APIView
from django.utils import timezone
from django.db.models import Count
from .models import ZabbixServer, MonitoringHost, MonitoringAlert, NotificationChannel, AlertNotification, EmailConfig, AlertRule
from django.http import StreamingHttpResponse
from django.views.decorators.csrf import csrf_exempt
import json
import uuid
from .serializers import (
    ZabbixServerSerializer, ZabbixServerCreateSerializer,
    MonitoringHostSerializer, MonitoringAlertSerializer,
    NotificationChannelSerializer, AlertNotificationSerializer, EmailConfigSerializer, AlertRuleSerializer
)
import logging


logger = logging.getLogger(__name__)


class ZabbixServerViewSet(viewsets.ModelViewSet):
    """Zabbix服务器管理"""
    queryset = ZabbixServer.objects.all()
    permission_classes = [IsAuthenticated]

    def get_serializer_class(self):
        if self.action in ['create', 'update', 'partial_update']:
            return ZabbixServerCreateSerializer
        return ZabbixServerSerializer

    def perform_create(self, serializer):
        serializer.save(created_by=self.request.user)

    def list(self, request, *args, **kwargs):
        """获取Zabbix服务器列表"""
        queryset = self.filter_queryset(self.get_queryset())
        serializer = self.get_serializer(queryset, many=True)
        return Response({
            'success': True,
            'data': serializer.data,
            'message': '获取成功'
        })

    def create(self, request, *args, **kwargs):
        """创建Zabbix服务器"""
        serializer = self.get_serializer(data=request.data)
        if serializer.is_valid():
            self.perform_create(serializer)
            return Response({
                'success': True,
                'data': serializer.data,
                'message': '创建成功'
            }, status=status.HTTP_201_CREATED)
        return Response({
            'success': False,
            'message': '创建失败',
            'errors': serializer.errors
        }, status=status.HTTP_400_BAD_REQUEST)

    def update(self, request, *args, **kwargs):
        """更新Zabbix服务器"""
        partial = kwargs.pop('partial', False)
        instance = self.get_object()
        serializer = self.get_serializer(instance, data=request.data, partial=partial)
        if serializer.is_valid():
            self.perform_update(serializer)
            return Response({
                'success': True,
                'data': serializer.data,
                'message': '更新成功'
            })
        return Response({
            'success': False,
            'message': '更新失败',
            'errors': serializer.errors
        }, status=status.HTTP_400_BAD_REQUEST)

    def destroy(self, request, *args, **kwargs):
        """删除Zabbix服务器"""
        instance = self.get_object()
        self.perform_destroy(instance)
        return Response({
            'success': True,
            'message': '删除成功'
        }, status=status.HTTP_200_OK)

    @action(detail=True, methods=['post'])
    def test_connection(self, request, pk=None):
        """测试Zabbix连接"""
        server = self.get_object()

        try:
            # 这里将在后续实现具体的连接测试逻辑
            from .utils.zabbix_api import ZabbixAPIManager

            api_manager = ZabbixAPIManager(server)
            result = api_manager.test_connection()

            if result['success']:
                server.connection_status = 'connected'
                server.last_check_time = timezone.now()
                server.error_message = ''
                server.save()

                return Response({
                    'success': True,
                    'message': '连接成功',
                    'data': result.get('data', {})
                })
            else:
                server.connection_status = 'disconnected'
                server.last_check_time = timezone.now()
                server.error_message = result.get('error', '连接失败')
                server.save()

                return Response({
                    'success': False,
                    'message': result.get('error', '连接失败')
                }, status=status.HTTP_400_BAD_REQUEST)

        except Exception as e:
            logger.error(f"测试Zabbix连接失败: {e}")
            server.connection_status = 'error'
            server.last_check_time = timezone.now()
            server.error_message = str(e)
            server.save()

            return Response({
                'success': False,
                'message': f'连接测试失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['get'])
    def templates(self, request, pk=None):
        """获取Zabbix模板列表"""
        server = self.get_object()

        try:
            from .utils.zabbix_api import ZabbixAPIManager

            api_manager = ZabbixAPIManager(server)
            if not api_manager._connect():
                return Response({
                    'success': False,
                    'message': 'Zabbix API连接失败'
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

            # 获取所有模板，包含详细信息
            templates = api_manager.zapi.template.get(
                output=['templateid', 'name', 'description', 'status'],
                selectItems=['itemid', 'name', 'key_', 'type', 'status'],
                selectTriggers=['triggerid', 'description', 'expression', 'priority', 'status'],
                selectGraphs=['graphid', 'name'],
                selectHosts=['hostid', 'name'],
                sortfield='name'
            )

            return Response({
                'success': True,
                'data': templates,
                'message': '获取模板列表成功'
            })

        except Exception as e:
            logger.error(f"获取Zabbix模板失败: {e}")
            return Response({
                'success': False,
                'message': f'获取模板失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['put'], url_path='update-template/(?P<template_id>[^/.]+)')
    def update_template(self, request, pk=None, template_id=None):
        """更新Zabbix模板"""
        server = self.get_object()

        try:
            from .utils.zabbix_api import ZabbixAPIManager

            api_manager = ZabbixAPIManager(server)
            if not api_manager._connect():
                return Response({
                    'success': False,
                    'message': 'Zabbix API连接失败'
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

            # 获取请求数据
            name = request.data.get('name')
            description = request.data.get('description', '')
            status = request.data.get('status', '0')

            if not name:
                return Response({
                    'success': False,
                    'message': '模板名称不能为空'
                }, status=status.HTTP_400_BAD_REQUEST)

            # 更新模板
            result = api_manager.zapi.template.update({
                'templateid': template_id,
                'name': name,
                'description': description,
                'status': int(status)
            })

            if result.get('templateids'):
                return Response({
                    'success': True,
                    'message': '模板更新成功',
                    'data': result
                })
            else:
                return Response({
                    'success': False,
                    'message': '模板更新失败'
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        except Exception as e:
            logger.error(f"更新Zabbix模板失败: {e}")
            return Response({
                'success': False,
                'message': f'更新模板失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['post'], url_path='clone-template/(?P<template_id>[^/.]+)')
    def clone_template(self, request, pk=None, template_id=None):
        """克隆Zabbix模板"""
        server = self.get_object()

        try:
            from .utils.zabbix_api import ZabbixAPIManager

            api_manager = ZabbixAPIManager(server)
            if not api_manager._connect():
                return Response({
                    'success': False,
                    'message': 'Zabbix API连接失败'
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

            # 获取请求数据
            new_name = request.data.get('name')
            new_description = request.data.get('description', '')

            if not new_name:
                return Response({
                    'success': False,
                    'message': '新模板名称不能为空'
                }, status=status.HTTP_400_BAD_REQUEST)

            # 清理模板名称，移除Zabbix不支持的特殊字符
            import re
            new_name = re.sub(r'[^\w\s\-_.]', '', new_name).strip()

            # 先获取原模板的完整信息
            source_template = api_manager.zapi.template.get(
                templateids=template_id,
                output='extend',
                selectItems='extend',
                selectTriggers='extend',
                selectGraphs='extend',
                selectMacros='extend'
            )

            if not source_template:
                return Response({
                    'success': False,
                    'message': '源模板不存在'
                }, status=status.HTTP_404_NOT_FOUND)

            source = source_template[0]

            # 创建新模板
            new_template_data = {
                'host': new_name,  # Zabbix中模板的host字段就是模板名称
                'name': new_name,
                'description': new_description,
                'groups': [{'groupid': '1'}],  # 默认分组
                'status': source.get('status', '0')
            }

            result = api_manager.zapi.template.create(new_template_data)

            if result.get('templateids'):
                return Response({
                    'success': True,
                    'message': '模板克隆成功',
                    'data': result
                })
            else:
                return Response({
                    'success': False,
                    'message': '模板克隆失败'
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        except Exception as e:
            logger.error(f"克隆Zabbix模板失败: {e}")
            return Response({
                'success': False,
                'message': f'克隆模板失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    def delete_template(self, request, pk=None, template_id=None):
        """删除Zabbix模板"""
        logger.info(f"开始删除模板，模板ID: {template_id}")
        server = self.get_object()

        try:
            from .utils.zabbix_api import ZabbixAPIManager

            api_manager = ZabbixAPIManager(server)
            if not api_manager._connect():
                return Response({
                    'success': False,
                    'message': 'Zabbix API连接失败'
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

            # 检查模板是否被主机使用
            hosts = api_manager.zapi.host.get(
                templateids=template_id,
                output=['hostid', 'name']
            )

            if hosts:
                host_names = [host['name'] for host in hosts]
                return Response({
                    'success': False,
                    'message': f'模板正在被以下主机使用，无法删除: {", ".join(host_names)}'
                }, status=status.HTTP_400_BAD_REQUEST)

            # 删除模板 - 直接使用JSON-RPC格式调用
            try:
                # 首先检查模板是否存在
                existing_templates = api_manager.zapi.template.get(
                    templateids=template_id,
                    output=['templateid', 'name']
                )

                if not existing_templates:
                    return Response({
                        'success': False,
                        'message': '模板不存在或已被删除'
                    }, status=status.HTTP_404_NOT_FOUND)

                # 使用原生JSON-RPC调用，直接传递模板ID数组作为params
                import requests
                import json

                # 构造JSON-RPC请求
                payload = {
                    "jsonrpc": "2.0",
                    "method": "template.delete",
                    "params": [template_id],  # 直接传递模板ID数组
                    "auth": api_manager.zapi.auth,
                    "id": 1
                }

                response = requests.post(
                    api_manager.zapi.url,
                    headers={"Content-Type": "application/json-rpc"},
                    data=json.dumps(payload)
                )

                result_data = response.json()
                if 'error' in result_data:
                    raise Exception(f"Zabbix API Error: {result_data['error']}")

                result = result_data.get('result', {})
                logger.info(f"模板删除成功，结果: {result}")
                return Response({
                    'success': True,
                    'message': '模板删除成功',
                    'data': result
                })
            except Exception as delete_error:
                # 如果是权限错误但模板实际被删除了，我们认为是成功的
                error_msg = str(delete_error)
                if "You do not have permission" in error_msg:
                    # 检查模板是否还存在
                    try:
                        check_result = api_manager.zapi.template.get(
                            templateids=[template_id],
                            output=['templateid']
                        )
                        if not check_result:
                            # 模板不存在了，说明删除成功
                            logger.info(f"模板 {template_id} 已被删除（权限错误但删除成功）")
                            return Response({
                                'success': True,
                                'message': '模板删除成功'
                            })
                    except:
                        pass

                # 真正的删除失败
                raise delete_error

        except Exception as e:
            logger.error(f"删除Zabbix模板失败: {e}")
            import traceback
            logger.error(f"删除模板异常堆栈: {traceback.format_exc()}")
            return Response({
                'success': False,
                'message': f'删除模板失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['post'], url_path='create-template')
    def create_template(self, request, pk=None):
        """创建Zabbix模板"""
        server = self.get_object()

        try:
            from .utils.zabbix_api import ZabbixAPIManager

            api_manager = ZabbixAPIManager(server)
            if not api_manager._connect():
                return Response({
                    'success': False,
                    'message': 'Zabbix API连接失败'
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

            # 获取请求数据
            name = request.data.get('name')
            description = request.data.get('description', '')
            groups = request.data.get('groups', ['1'])  # 默认分组ID

            # 确保groups格式正确
            if isinstance(groups, list) and len(groups) > 0:
                if isinstance(groups[0], str):
                    # 如果是字符串数组，转换为对象数组
                    groups = [{'groupid': gid} for gid in groups]
            else:
                groups = [{'groupid': '1'}]  # 默认Templates组

            if not name:
                return Response({
                    'success': False,
                    'message': '模板名称不能为空'
                }, status=status.HTTP_400_BAD_REQUEST)

            # 创建模板
            template_data = {
                'host': name,  # Zabbix中模板的host字段就是模板名称
                'name': name,
                'description': description,
                'groups': groups,
                'status': '0'  # 默认启用
            }

            result = api_manager.zapi.template.create(template_data)

            if result.get('templateids'):
                return Response({
                    'success': True,
                    'message': '模板创建成功',
                    'data': result
                })
            else:
                return Response({
                    'success': False,
                    'message': '模板创建失败'
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        except Exception as e:
            logger.error(f"创建Zabbix模板失败: {e}")
            return Response({
                'success': False,
                'message': f'创建模板失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['get'])
    def test_action(self, request, pk=None):
        """测试action"""
        return Response({'success': True, 'message': 'Test action works'})

    @action(detail=True, methods=['get'])
    def items(self, request, pk=None):
        """获取Zabbix监控项列表"""
        server = self.get_object()

        try:
            from .utils.zabbix_api import ZabbixAPIManager

            api_manager = ZabbixAPIManager(server)
            if not api_manager._connect():
                return Response({
                    'success': False,
                    'message': 'Zabbix API连接失败'
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

            # 获取所有监控项，包含最新值
            items = api_manager.zapi.item.get(
                output=['itemid', 'name', 'key_', 'hostid', 'type', 'value_type',
                       'delay', 'units', 'description', 'status', 'lastvalue',
                       'lastclock', 'params', 'username', 'timeout', 'history', 'trends'],
                selectHosts=['hostid', 'name'],
                sortfield='name',
                limit=1000  # 限制返回数量，避免性能问题
            )

            return Response({
                'success': True,
                'data': items,
                'message': '获取监控项列表成功'
            })

        except Exception as e:
            logger.error(f"获取Zabbix监控项失败: {e}")
            return Response({
                'success': False,
                'message': f'获取监控项失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['post'])
    def create_item(self, request, pk=None):
        """创建Zabbix监控项"""
        server = self.get_object()

        try:
            from .utils.zabbix_api import ZabbixAPIManager

            api_manager = ZabbixAPIManager(server)
            if not api_manager._connect():
                return Response({
                    'success': False,
                    'message': 'Zabbix API连接失败'
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

            # 获取请求数据
            data = request.data

            # 检查是在模板中创建还是在主机中创建
            if data.get('templateid'):
                # 在模板中创建监控项
                required_fields = ['name', 'key_', 'templateid', 'type', 'value_type']

                # 验证必填字段
                for field in required_fields:
                    if not data.get(field):
                        return Response({
                            'success': False,
                            'message': f'缺少必填字段: {field}'
                        }, status=status.HTTP_400_BAD_REQUEST)

                # 构建监控项参数（模板）
                item_params = {
                    'name': data['name'],
                    'key_': data['key_'],
                    'hostid': data['templateid'],  # 在模板中创建时，hostid实际上是templateid
                    'type': int(data['type']),
                    'value_type': int(data['value_type']),
                    'delay': data.get('delay', '30s'),
                    'units': data.get('units', ''),
                    'description': data.get('description', ''),
                    'status': int(data.get('status', '0'))
                }
            else:
                # 在主机中创建监控项（原有逻辑）
                required_fields = ['name', 'key_', 'hostid', 'type', 'value_type']

                # 验证必填字段
                for field in required_fields:
                    if not data.get(field):
                        return Response({
                            'success': False,
                            'message': f'缺少必填字段: {field}'
                        }, status=status.HTTP_400_BAD_REQUEST)

                # 构建监控项参数（主机）
                item_params = {
                    'name': data['name'],
                    'key_': data['key_'],
                    'hostid': data['hostid'],
                    'type': int(data['type']),
                    'value_type': int(data['value_type']),
                    'delay': data.get('delay', '30s'),
                    'units': data.get('units', ''),
                    'description': data.get('description', ''),
                    'status': int(data.get('status', '0'))
                }

            # 添加可选参数
            if data.get('history'):
                item_params['history'] = data['history']
            if data.get('trends'):
                item_params['trends'] = data['trends']
            if data.get('params'):
                item_params['params'] = data['params']
            if data.get('username'):
                item_params['username'] = data['username']
            if data.get('timeout'):
                item_params['timeout'] = data['timeout']

            # 创建监控项
            result = api_manager.zapi.item.create(item_params)

            logger.info(f"创建监控项成功: {result}")

            return Response({
                'success': True,
                'data': result,
                'message': '监控项创建成功'
            })

        except Exception as e:
            logger.error(f"创建监控项失败: {e}")
            return Response({
                'success': False,
                'message': f'创建监控项失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['put'])
    def update_item(self, request, pk=None):
        """更新Zabbix监控项"""
        server = self.get_object()

        try:
            from .utils.zabbix_api import ZabbixAPIManager

            api_manager = ZabbixAPIManager(server)
            if not api_manager._connect():
                return Response({
                    'success': False,
                    'message': 'Zabbix API连接失败'
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

            # 获取请求数据
            data = request.data

            # 从请求数据中获取item_id
            item_id = data.get('itemid')
            if not item_id:
                return Response({
                    'success': False,
                    'message': '缺少监控项ID'
                }, status=status.HTTP_400_BAD_REQUEST)

            # 构建更新参数
            update_params = {'itemid': item_id}

            # 添加需要更新的字段
            updatable_fields = ['name', 'key_', 'type', 'value_type', 'delay',
                              'units', 'description', 'status', 'history', 'trends',
                              'params', 'username', 'timeout']

            for field in updatable_fields:
                if field in data:
                    if field in ['type', 'value_type', 'status']:
                        update_params[field] = int(data[field])
                    else:
                        update_params[field] = data[field]

            # 更新监控项
            result = api_manager.zapi.item.update(update_params)

            logger.info(f"更新监控项 {item_id} 成功: {result}")

            return Response({
                'success': True,
                'data': result,
                'message': '监控项更新成功'
            })

        except Exception as e:
            logger.error(f"更新监控项失败: {e}")
            return Response({
                'success': False,
                'message': f'更新监控项失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['delete'])
    def delete_item_action(self, request, pk=None):
        """删除Zabbix监控项"""
        server = self.get_object()

        try:
            from .utils.zabbix_api import ZabbixAPIManager

            api_manager = ZabbixAPIManager(server)
            if not api_manager._connect():
                return Response({
                    'success': False,
                    'message': 'Zabbix API连接失败'
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

            # 从请求数据中获取item_id
            item_id = request.data.get('itemid')
            if not item_id:
                return Response({
                    'success': False,
                    'message': '缺少监控项ID'
                }, status=status.HTTP_400_BAD_REQUEST)

            # 确保item_id是数字类型（Zabbix API要求）
            try:
                item_id_int = int(item_id)
            except (ValueError, TypeError):
                return Response({
                    'success': False,
                    'message': '监控项ID必须是数字'
                }, status=status.HTTP_400_BAD_REQUEST)

            # 删除监控项 - 使用正确的Zabbix API调用方式
            result = api_manager.zapi.item.delete(str(item_id_int))

            logger.info(f"删除监控项 {item_id} 成功: {result}")

            return Response({
                'success': True,
                'data': result,
                'message': '监控项删除成功'
            })

        except Exception as e:
            logger.error(f"删除监控项失败: {e}")
            return Response({
                'success': False,
                'message': f'删除监控项失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['post'])
    def test_item(self, request, pk=None):
        """测试Zabbix监控项"""
        server = self.get_object()

        try:
            from .utils.zabbix_api import ZabbixAPIManager

            api_manager = ZabbixAPIManager(server)
            if not api_manager._connect():
                return Response({
                    'success': False,
                    'message': 'Zabbix API连接失败'
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

            # 从请求数据中获取item_id
            item_id = request.data.get('itemid')
            if not item_id:
                return Response({
                    'success': False,
                    'message': '缺少监控项ID'
                }, status=status.HTTP_400_BAD_REQUEST)

            # 获取监控项详情
            item_info = api_manager.zapi.item.get(
                output=['itemid', 'name', 'key_', 'hostid', 'type', 'lastvalue', 'lastclock'],
                itemids=[item_id],
                selectHosts=['hostid', 'name']
            )

            if not item_info:
                return Response({
                    'success': False,
                    'message': '监控项不存在'
                }, status=status.HTTP_404_NOT_FOUND)

            item = item_info[0]

            # 获取主机信息
            hosts = item.get('hosts', [])
            if not hosts:
                return Response({
                    'success': False,
                    'message': '监控项未关联任何主机'
                }, status=status.HTTP_400_BAD_REQUEST)

            host = hosts[0]
            host_name = host.get('name', '')
            item_key = item.get('key_', '')

            # 使用zabbix_get命令测试监控项
            import subprocess
            import json

            zabbix_get_result = None
            zabbix_get_error = None

            try:
                # 执行zabbix_get命令
                cmd = ['zabbix_get', '-s', host_name, '-k', item_key]
                logger.info(f"执行zabbix_get命令: {' '.join(cmd)}")

                result = subprocess.run(
                    cmd,
                    capture_output=True,
                    text=True,
                    timeout=30
                )

                if result.returncode == 0:
                    zabbix_get_result = result.stdout.strip()
                    logger.info(f"zabbix_get成功: {zabbix_get_result}")
                else:
                    zabbix_get_error = result.stderr.strip() or result.stdout.strip()
                    logger.error(f"zabbix_get失败: {zabbix_get_error}")

            except subprocess.TimeoutExpired:
                zabbix_get_error = "zabbix_get命令执行超时"
                logger.error(zabbix_get_error)
            except FileNotFoundError:
                zabbix_get_error = "zabbix_get命令未找到，请确保已安装zabbix-get工具"
                logger.error(zabbix_get_error)
            except Exception as e:
                zabbix_get_error = f"执行zabbix_get命令时发生错误: {str(e)}"
                logger.error(zabbix_get_error)

            # 获取最新历史数据
            try:
                history = api_manager.zapi.history.get(
                    output='extend',
                    itemids=[item_id],
                    sortfield='clock',
                    sortorder='DESC',
                    limit=1
                )
            except:
                history = []

            test_result = {
                'item_info': item,
                'host_name': host_name,
                'item_key': item_key,
                'zabbix_get_result': zabbix_get_result,
                'zabbix_get_error': zabbix_get_error,
                'zabbix_get_success': zabbix_get_result is not None,
                'latest_value': item.get('lastvalue', 'N/A'),
                'last_check': item.get('lastclock', 'N/A'),
                'history': history[0] if history else None,
                'test_time': timezone.now().isoformat()
            }

            return Response({
                'success': True,
                'data': test_result,
                'message': '监控项测试完成'
            })

        except Exception as e:
            logger.error(f"测试监控项失败: {e}")
            return Response({
                'success': False,
                'message': f'测试监控项失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['post'], url_path='batch-delete-items')
    def batch_delete_items(self, request, pk=None):
        """批量删除Zabbix监控项"""
        server = self.get_object()

        try:
            from .utils.zabbix_api import ZabbixAPIManager

            api_manager = ZabbixAPIManager(server)
            if not api_manager._connect():
                return Response({
                    'success': False,
                    'message': 'Zabbix API连接失败'
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

            # 获取要删除的监控项ID列表
            item_ids = request.data.get('item_ids', [])
            if not item_ids:
                return Response({
                    'success': False,
                    'message': '请选择要删除的监控项'
                }, status=status.HTTP_400_BAD_REQUEST)

            # 批量删除监控项
            result = api_manager.zapi.item.delete(item_ids)

            logger.info(f"批量删除监控项成功: {result}")

            return Response({
                'success': True,
                'data': result,
                'message': f'成功删除 {len(item_ids)} 个监控项'
            })

        except Exception as e:
            logger.error(f"批量删除监控项失败: {e}")
            return Response({
                'success': False,
                'message': f'批量删除监控项失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['get'])
    def get_item_history(self, request, pk=None):
        """获取监控项历史数据 - 按照Zabbix 5.0 API规范"""
        server = self.get_object()

        try:
            from .utils.zabbix_api import ZabbixAPIManager
            from datetime import datetime
            import time

            api_manager = ZabbixAPIManager(server)
            if not api_manager._connect():
                return Response({
                    'success': False,
                    'message': 'Zabbix API连接失败'
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

            # 从查询参数中获取必要参数
            host_name = request.query_params.get('host_name')
            item_name = request.query_params.get('item_name')
            item_key = request.query_params.get('item_key')
            time_range = int(request.query_params.get('time_range', 3600))  # 默认1小时
            limit = int(request.query_params.get('limit', 100))

            if not host_name or not (item_name or item_key):
                return Response({
                    'success': False,
                    'message': '缺少必要参数：host_name 和 (item_name 或 item_key)'
                }, status=status.HTTP_400_BAD_REQUEST)

            # 1. 获取主机ID
            hosts = api_manager.zapi.host.get(
                output=['hostid', 'name'],
                filter={'name': [host_name]}
            )

            if not hosts:
                return Response({
                    'success': False,
                    'message': f'主机 "{host_name}" 不存在'
                }, status=status.HTTP_404_NOT_FOUND)

            host_id = hosts[0]['hostid']

            # 2. 获取监控项ID
            item_filter = {'hostid': host_id}
            if item_key:
                item_filter['key_'] = item_key
            elif item_name:
                item_filter['name'] = item_name

            items = api_manager.zapi.item.get(
                output=['itemid', 'name', 'key_', 'value_type', 'units'],
                filter=item_filter
            )

            if not items:
                search_term = item_key if item_key else item_name
                return Response({
                    'success': False,
                    'message': f'在主机 "{host_name}" 上未找到监控项 "{search_term}"'
                }, status=status.HTTP_404_NOT_FOUND)

            item = items[0]
            item_id = item['itemid']
            value_type = int(item.get('value_type', 0))

            # 3. 计算时间范围
            now = int(time.time())
            time_from = now - time_range
            time_till = now

            # 4. 根据值类型获取历史数据
            logger.info(f"开始获取历史数据: 主机={host_name}, 监控项={item['name']}, itemid={item_id}, value_type={value_type}")
            history_data = []
            try:
                if value_type == 0:  # 浮点数类型
                    logger.info(f"获取浮点数类型历史数据: time_from={time_from}, time_till={time_till}")
                    history_data = api_manager.zapi.history.get(
                        history=0,
                        output='extend',
                        itemids=[item_id],
                        time_from=time_from,
                        time_till=time_till,
                        sortfield='clock',
                        sortorder='DESC',
                        limit=limit
                    )
                    logger.info(f"获取到浮点数历史数据: {len(history_data)} 条")
                elif value_type == 1:  # 字符串类型
                    history_data = api_manager.zapi.history.get(
                        history=1,
                        output='extend',
                        itemids=[item_id],
                        time_from=time_from,
                        time_till=time_till,
                        sortfield='clock',
                        sortorder='DESC',
                        limit=limit
                    )
                elif value_type == 2:  # 日志类型
                    history_data = api_manager.zapi.history.get(
                        history=2,
                        output='extend',
                        itemids=[item_id],
                        time_from=time_from,
                        time_till=time_till,
                        sortfield='clock',
                        sortorder='DESC',
                        limit=limit
                    )
                elif value_type == 3:  # 无符号整数类型
                    history_data = api_manager.zapi.history.get(
                        history=3,
                        output='extend',
                        itemids=[item_id],
                        time_from=time_from,
                        time_till=time_till,
                        sortfield='clock',
                        sortorder='DESC',
                        limit=limit
                    )
                elif value_type == 4:  # 文本类型
                    history_data = api_manager.zapi.history.get(
                        history=4,
                        output='extend',
                        itemids=[item_id],
                        time_from=time_from,
                        time_till=time_till,
                        sortfield='clock',
                        sortorder='DESC',
                        limit=limit
                    )
            except Exception as history_error:
                logger.warning(f"获取历史数据失败，尝试不带时间范围: {history_error}")
                # 如果带时间范围失败，尝试不带时间范围
                try:
                    if value_type == 0:
                        history_data = api_manager.zapi.history.get(
                            history=0,
                            output='extend',
                            itemids=[item_id],
                            sortfield='clock',
                            sortorder='DESC',
                            limit=limit
                        )
                    elif value_type == 3:
                        history_data = api_manager.zapi.history.get(
                            history=3,
                            output='extend',
                            itemids=[item_id],
                            sortfield='clock',
                            sortorder='DESC',
                            limit=limit
                        )
                except Exception as fallback_error:
                    logger.error(f"获取历史数据完全失败: {fallback_error}")
                    history_data = []

            # 5. 格式化历史数据
            formatted_data = []
            for record in history_data:
                try:
                    clock = int(record.get('clock', 0))
                    value = record.get('value', '')

                    # 尝试转换数值
                    if value_type in [0, 3] and value:
                        try:
                            value = float(value)
                        except (ValueError, TypeError):
                            pass

                    formatted_data.append({
                        'clock': clock,
                        'value': value,
                        'timestamp': datetime.fromtimestamp(clock).isoformat() if clock > 0 else None,
                        'formatted_time': datetime.fromtimestamp(clock).strftime('%Y-%m-%d %H:%M:%S') if clock > 0 else None
                    })
                except Exception as format_error:
                    logger.warning(f"格式化历史数据记录失败: {format_error}")
                    continue

            return Response({
                'success': True,
                'data': formatted_data,
                'item_info': {
                    'itemid': item_id,
                    'name': item['name'],
                    'key': item['key_'],
                    'value_type': value_type,
                    'units': item.get('units', ''),
                    'host_name': host_name
                },
                'message': f'获取到 {len(formatted_data)} 条历史数据'
            })

        except Exception as e:
            logger.error(f"获取监控项历史数据失败: {e}")
            return Response({
                'success': False,
                'message': f'获取历史数据失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    def export_template(self, request, pk=None, template_id=None):
        """导出Zabbix模板"""
        server = self.get_object()

        if not template_id:
            return Response({
                'success': False,
                'message': '缺少模板ID参数'
            }, status=status.HTTP_400_BAD_REQUEST)

        try:
            from .utils.zabbix_api import ZabbixAPIManager

            api_manager = ZabbixAPIManager(server)
            if not api_manager._connect():
                return Response({
                    'success': False,
                    'message': 'Zabbix API连接失败'
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

            # 导出模板
            result = api_manager.zapi.do_request('configuration.export', {
                'format': 'xml',
                'options': {
                    'templates': [template_id]
                }
            })

            if result:
                return Response({
                    'success': True,
                    'data': result,
                    'message': '模板导出成功'
                })
            else:
                return Response({
                    'success': False,
                    'message': '模板导出失败'
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        except Exception as e:
            logger.error(f"导出Zabbix模板失败: {e}")
            return Response({
                'success': False,
                'message': f'导出模板失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['post'])
    def batch_export_templates(self, request, pk=None):
        """批量导出Zabbix模板"""
        server = self.get_object()

        template_ids = request.data.get('template_ids', [])
        if not template_ids:
            return Response({
                'success': False,
                'message': '请选择要导出的模板'
            }, status=status.HTTP_400_BAD_REQUEST)

        try:
            from .utils.zabbix_api import ZabbixAPIManager
            import zipfile
            import io
            from django.http import HttpResponse

            api_manager = ZabbixAPIManager(server)
            if not api_manager._connect():
                return Response({
                    'success': False,
                    'message': 'Zabbix API连接失败'
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

            # 创建ZIP文件
            zip_buffer = io.BytesIO()

            with zipfile.ZipFile(zip_buffer, 'w', zipfile.ZIP_DEFLATED) as zip_file:
                for template_id in template_ids:
                    try:
                        # 获取模板信息
                        template_info = api_manager.zapi.template.get(
                            templateids=[template_id],
                            output=['templateid', 'name']
                        )

                        if not template_info:
                            continue

                        template_name = template_info[0]['name']

                        # 导出模板
                        result = api_manager.zapi.do_request('configuration.export', {
                            'format': 'xml',
                            'options': {
                                'templates': [template_id]
                            }
                        })

                        # 从API响应中提取XML内容
                        xml_content = None
                        if result and isinstance(result, dict) and 'result' in result:
                            xml_content = result['result']
                        elif isinstance(result, str):
                            xml_content = result

                        if xml_content:
                            # 清理文件名中的特殊字符
                            safe_filename = "".join(c for c in template_name if c.isalnum() or c in (' ', '-', '_', '.')).rstrip()
                            filename = f"{safe_filename}_template.xml"
                            zip_file.writestr(filename, xml_content)
                        else:
                            logger.error(f"模板 {template_id} ({template_name}) 导出失败")

                    except Exception as e:
                        logger.error(f"导出模板 {template_id} 失败: {e}")
                        continue

            zip_buffer.seek(0)

            # 返回ZIP文件
            response = HttpResponse(
                zip_buffer.getvalue(),
                content_type='application/zip'
            )
            response['Content-Disposition'] = f'attachment; filename="zabbix_templates_export_{len(template_ids)}.zip"'
            return response

        except Exception as e:
            logger.error(f"批量导出Zabbix模板失败: {e}")
            return Response({
                'success': False,
                'message': f'批量导出模板失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['post'])
    def batch_import_templates(self, request, pk=None):
        """批量导入Zabbix模板（ZIP文件）"""
        server = self.get_object()

        if 'file' not in request.FILES:
            return Response({
                'success': False,
                'message': '请选择要导入的ZIP文件'
            }, status=status.HTTP_400_BAD_REQUEST)

        zip_file = request.FILES['file']

        # 验证文件类型
        if not zip_file.name.endswith('.zip'):
            return Response({
                'success': False,
                'message': '请上传ZIP格式的文件'
            }, status=status.HTTP_400_BAD_REQUEST)

        try:
            from .utils.zabbix_api import ZabbixAPIManager
            import zipfile
            import tempfile
            import os

            api_manager = ZabbixAPIManager(server)
            if not api_manager._connect():
                return Response({
                    'success': False,
                    'message': 'Zabbix API连接失败'
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

            success_count = 0
            failed_count = 0
            failed_files = []

            # 创建临时目录处理ZIP文件
            with tempfile.TemporaryDirectory() as temp_dir:
                # 保存上传的ZIP文件
                zip_path = os.path.join(temp_dir, zip_file.name)
                with open(zip_path, 'wb') as f:
                    for chunk in zip_file.chunks():
                        f.write(chunk)

                # 解压ZIP文件
                with zipfile.ZipFile(zip_path, 'r') as zip_ref:
                    zip_ref.extractall(temp_dir)

                # 遍历解压后的文件
                for root, dirs, files in os.walk(temp_dir):
                    for file in files:
                        if file.endswith('.xml') and file != zip_file.name:
                            file_path = os.path.join(root, file)
                            try:
                                # 读取XML文件内容
                                with open(file_path, 'r', encoding='utf-8') as xml_file:
                                    xml_content = xml_file.read()

                                # 导入模板 - 使用ZabbixAPI对象
                                try:
                                    # 使用do_request方法直接调用Zabbix API
                                    result = api_manager.zapi.do_request('configuration.import', {
                                        "format": "xml",
                                        "source": xml_content,
                                        "rules": {
                                            "groups": {
                                                "createMissing": True
                                                # Zabbix 5.0不支持updateExisting参数
                                            },
                                            "templates": {
                                                "createMissing": True,
                                                "updateExisting": True
                                            },
                                            "applications": {
                                                "createMissing": True
                                                # Zabbix 5.0不支持updateExisting参数
                                            },
                                            "items": {
                                                "createMissing": True,
                                                "updateExisting": True
                                            },
                                            "discoveryRules": {
                                                "createMissing": True,
                                                "updateExisting": True
                                            },
                                            "triggers": {
                                                "createMissing": True,
                                                "updateExisting": True
                                            },
                                            "graphs": {
                                                "createMissing": True,
                                                "updateExisting": True
                                            },
                                            "valueMaps": {
                                                "createMissing": True,
                                                "updateExisting": True
                                            }
                                        }
                                    })
                                except Exception as api_error:
                                    raise Exception(f"Zabbix API调用失败: {str(api_error)}")

                                if result:
                                    success_count += 1
                                    logger.info(f"成功导入模板文件: {file}")
                                else:
                                    failed_count += 1
                                    failed_files.append(file)
                                    logger.error(f"导入模板文件失败: {file}")

                            except Exception as e:
                                failed_count += 1
                                failed_files.append(f"{file}: {str(e)}")
                                logger.error(f"导入模板文件 {file} 失败: {e}")

            # 构建响应消息
            if success_count > 0 and failed_count == 0:
                message = f'批量导入成功！共导入 {success_count} 个模板'
            elif success_count > 0 and failed_count > 0:
                message = f'部分导入成功！成功导入 {success_count} 个模板，失败 {failed_count} 个'
                if failed_files:
                    message += f'。失败文件: {", ".join(failed_files[:3])}'
                    if len(failed_files) > 3:
                        message += f' 等{len(failed_files)}个文件'
            else:
                message = f'批量导入失败！共 {failed_count} 个文件导入失败'
                if failed_files:
                    message += f'。失败文件: {", ".join(failed_files[:3])}'
                    if len(failed_files) > 3:
                        message += f' 等{len(failed_files)}个文件'

            return Response({
                'success': success_count > 0,
                'message': message,
                'details': {
                    'success_count': success_count,
                    'failed_count': failed_count,
                    'failed_files': failed_files
                }
            })

        except Exception as e:
            logger.error(f"批量导入Zabbix模板失败: {e}")
            return Response({
                'success': False,
                'message': f'批量导入模板失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    def import_template(self, request, pk=None):
        """导入Zabbix模板"""
        server = self.get_object()

        try:
            from .utils.zabbix_api import ZabbixAPIManager

            api_manager = ZabbixAPIManager(server)
            if not api_manager._connect():
                return Response({
                    'success': False,
                    'message': 'Zabbix API连接失败'
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

            # 获取上传的文件
            uploaded_file = request.FILES.get('file')
            if not uploaded_file:
                return Response({
                    'success': False,
                    'message': '请选择要导入的模板文件'
                }, status=status.HTTP_400_BAD_REQUEST)

            # 读取文件内容
            file_content = uploaded_file.read().decode('utf-8')

            # 导入模板 - 使用原生JSON-RPC调用
            import requests
            import json

            # 构造JSON-RPC请求 - 使用Zabbix 5.0兼容的导入规则
            payload = {
                "jsonrpc": "2.0",
                "method": "configuration.import",
                "params": {
                    "format": "xml",
                    "source": file_content,
                    "rules": {
                        "groups": {
                            "createMissing": True
                            # Zabbix 5.0不支持updateExisting参数
                        },
                        "templates": {
                            "createMissing": True,
                            "updateExisting": True
                        },
                        "applications": {
                            "createMissing": True
                            # Zabbix 5.0不支持updateExisting参数
                        },
                        "items": {
                            "createMissing": True,
                            "updateExisting": True
                        },
                        "discoveryRules": {
                            "createMissing": True,
                            "updateExisting": True
                        },
                        "triggers": {
                            "createMissing": True,
                            "updateExisting": True
                        },
                        "graphs": {
                            "createMissing": True,
                            "updateExisting": True
                        },
                        "valueMaps": {
                            "createMissing": True,
                            "updateExisting": True
                        }
                    }
                },
                "auth": api_manager.zapi.auth,
                "id": 1
            }

            response = requests.post(
                api_manager.zapi.url,
                headers={"Content-Type": "application/json-rpc"},
                data=json.dumps(payload)
            )

            result_data = response.json()
            if 'error' in result_data:
                error_info = result_data['error']
                error_message = f"Zabbix API Error: Code {error_info.get('code', 'Unknown')}, Message: {error_info.get('message', 'Unknown')}"
                if 'data' in error_info:
                    error_message += f", Details: {error_info['data']}"
                raise Exception(error_message)

            result = result_data.get('result', {})

            # Zabbix 5.0的configuration.import在成功时返回True
            if result is True or result:
                return Response({
                    'success': True,
                    'data': result,
                    'message': '模板导入成功'
                })
            else:
                return Response({
                    'success': False,
                    'message': '模板导入失败：未知错误'
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        except Exception as e:
            logger.error(f"导入Zabbix模板失败: {e}")
            return Response({
                'success': False,
                'message': f'导入模板失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


# GrafanaServerViewSet已移除，使用Zabbix原生仪表板功能


class MonitoringHostViewSet(viewsets.ModelViewSet):
    """监控主机管理"""
    queryset = MonitoringHost.objects.all()
    serializer_class = MonitoringHostSerializer
    permission_classes = [IsAuthenticated]


class MonitoringAlertViewSet(viewsets.ModelViewSet):
    """监控告警管理"""
    queryset = MonitoringAlert.objects.all()
    serializer_class = MonitoringAlertSerializer
    permission_classes = [IsAuthenticated]

    def destroy(self, request, *args, **kwargs):
        """删除告警 - 标记为已删除而不是物理删除"""
        try:
            alert = self.get_object()
            alert_id = alert.id
            alert_title = alert.title

            # 标记为已删除，而不是物理删除
            alert.status = 'deleted'
            alert.save()

            logger.info(f"告警标记删除成功: ID={alert_id}, 标题={alert_title}")

            return Response({
                'success': True,
                'message': '告警删除成功'
            }, status=status.HTTP_200_OK)
        except Exception as e:
            logger.error(f"删除告警失败: {e}")
            return Response({
                'success': False,
                'message': f'删除告警失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    def get_queryset(self):
        queryset = super().get_queryset().select_related('host', 'zabbix_server', 'acknowledged_by')

        # 默认过滤掉已删除的告警
        queryset = queryset.exclude(status='deleted')

        # 过滤参数 - 安全地获取query_params
        if hasattr(self.request, 'query_params'):
            status_filter = self.request.query_params.get('status')
            severity_filter = self.request.query_params.get('severity')
            host_filter = self.request.query_params.get('host')

            # 如果明确请求显示已删除的告警
            show_deleted = self.request.query_params.get('show_deleted')
            if show_deleted == 'true':
                queryset = super().get_queryset().select_related('host', 'zabbix_server', 'acknowledged_by')

            if status_filter:
                queryset = queryset.filter(status=status_filter)
            if severity_filter:
                queryset = queryset.filter(severity=severity_filter)
            if host_filter:
                queryset = queryset.filter(host__hostname__icontains=host_filter)

        return queryset

    @action(detail=True, methods=['post'])
    def acknowledge(self, request, pk=None):
        """确认告警"""
        try:
            alert = self.get_object()
            message = request.data.get('message', '')

            alert.status = 'acknowledged'
            alert.acknowledged_time = timezone.now()
            alert.acknowledged_by = request.user
            alert.acknowledgment_message = message
            alert.save()

            return Response({
                'success': True,
                'message': '告警已确认'
            })
        except Exception as e:
            return Response({
                'success': False,
                'message': f'确认告警失败: {str(e)}'
            }, status=status.HTTP_400_BAD_REQUEST)


class AlertRuleViewSet(viewsets.ModelViewSet):
    """告警规则管理"""
    queryset = AlertRule.objects.all()
    serializer_class = AlertRuleSerializer
    permission_classes = [IsAuthenticated]

    def get_queryset(self):
        queryset = super().get_queryset().select_related('zabbix_server', 'created_by')

        # 过滤参数
        if hasattr(self.request, 'query_params'):
            zabbix_server_id = self.request.query_params.get('zabbix_server_id')
            is_active = self.request.query_params.get('is_active')
            severity = self.request.query_params.get('severity')

            if zabbix_server_id:
                queryset = queryset.filter(zabbix_server_id=zabbix_server_id)
            if is_active is not None:
                queryset = queryset.filter(is_active=is_active.lower() == 'true')
            if severity:
                queryset = queryset.filter(severity=severity)

        return queryset

    def perform_create(self, serializer):
        """创建告警规则时设置创建者"""
        serializer.save(created_by=self.request.user)

    @action(detail=True, methods=['post'])
    def toggle_active(self, request, pk=None):
        """切换规则启用状态"""
        try:
            rule = self.get_object()
            rule.is_active = not rule.is_active
            rule.save()

            return Response({
                'success': True,
                'message': f'规则已{"启用" if rule.is_active else "禁用"}',
                'is_active': rule.is_active
            })
        except Exception as e:
            return Response({
                'success': False,
                'message': f'切换规则状态失败: {str(e)}'
            }, status=status.HTTP_400_BAD_REQUEST)

    @action(detail=True, methods=['post'])
    def test_rule(self, request, pk=None):
        """测试告警规则"""
        try:
            rule = self.get_object()

            # 创建测试告警
            from .models import MonitoringAlert
            from .utils.notification_service import NotificationService
            from cmdb.models import Host

            # 获取一个测试主机（如果没有主机，使用None）
            test_host = Host.objects.first()

            # 创建测试告警
            test_alert = MonitoringAlert.objects.create(
                title=f'[测试告警] {rule.name}',
                description=f'这是一个测试告警，用于验证告警规则 "{rule.name}" 的通知配置是否正确。\n\n规则详情：\n- 监控项：{rule.metric_name}\n- 条件：{rule.get_condition_display()} {rule.threshold_value}\n- 严重级别：{rule.get_severity_display()}\n- 持续时间：{rule.duration}秒',
                severity=rule.severity,
                status='active',
                host=test_host,
                zabbix_server=rule.zabbix_server,
                event_time=timezone.now(),
                zabbix_event_id=f'test-{rule.id}-{timezone.now().timestamp()}'
            )

            # 发送测试通知
            notification_service = NotificationService()

            # 获取规则配置的通知渠道
            rule_channels = rule.notification_channels.filter(is_active=True)

            if rule_channels.exists():
                sent_channels = []
                failed_channels = []

                for channel in rule_channels:
                    try:
                        notification_service._send_single_notification(test_alert, channel)
                        sent_channels.append(channel.name)
                        logger.info(f"测试通知发送成功 - 规则: {rule.name}, 渠道: {channel.name}")
                    except Exception as e:
                        failed_channels.append(f"{channel.name}: {str(e)}")
                        logger.error(f"测试通知发送失败 - 规则: {rule.name}, 渠道: {channel.name}, 错误: {e}")

                # 删除测试告警
                test_alert.delete()

                # 构造响应消息
                message_parts = [f'规则 "{rule.name}" 测试完成']
                if sent_channels:
                    message_parts.append(f'成功发送到: {", ".join(sent_channels)}')
                if failed_channels:
                    message_parts.append(f'发送失败: {"; ".join(failed_channels)}')

                return Response({
                    'success': len(failed_channels) == 0,
                    'message': '\n'.join(message_parts),
                    'test_result': {
                        'rule_name': rule.name,
                        'sent_channels': sent_channels,
                        'failed_channels': failed_channels,
                        'total_channels': len(rule_channels)
                    }
                })
            else:
                # 删除测试告警
                test_alert.delete()

                return Response({
                    'success': False,
                    'message': f'规则 "{rule.name}" 没有配置激活的通知渠道'
                })

        except Exception as e:
            logger.error(f"测试告警规则失败: {e}")
            return Response({
                'success': False,
                'message': f'测试规则失败: {str(e)}'
            }, status=status.HTTP_400_BAD_REQUEST)


class NotificationChannelViewSet(viewsets.ModelViewSet):
    """通知渠道管理"""
    queryset = NotificationChannel.objects.all()
    serializer_class = NotificationChannelSerializer
    permission_classes = [IsAuthenticated]

    def get_queryset(self):
        """获取通知渠道列表，包括从邮件配置同步的渠道"""
        # 先同步邮件配置为通知渠道
        self._sync_email_configs_to_channels()
        return super().get_queryset()

    def _sync_email_configs_to_channels(self):
        """将邮件配置同步为通知渠道"""
        try:
            from .models import EmailConfig

            # 获取所有邮件配置
            email_configs = EmailConfig.objects.all()

            for email_config in email_configs:
                # 检查是否已经存在对应的通知渠道
                channel_name = f"邮件-{email_config.name}"
                existing_channel = NotificationChannel.objects.filter(
                    name=channel_name,
                    channel_type='email'
                ).first()

                # 准备邮件配置数据
                recipients = []
                if email_config.default_recipients:
                    recipients = [email.strip() for email in email_config.default_recipients.split(',') if email.strip()]

                config_data = {
                    'smtp_server': email_config.smtp_server,
                    'smtp_port': email_config.smtp_port,
                    'username': email_config.username,
                    'password': email_config.password,
                    'from_email': email_config.from_email,
                    'recipients': recipients,
                    'use_tls': email_config.use_tls,
                    'use_ssl': email_config.use_ssl,
                    'email_config_id': email_config.id  # 保存原始邮件配置ID
                }

                if existing_channel:
                    # 更新现有渠道
                    existing_channel.config = config_data
                    existing_channel.is_active = email_config.is_active
                    existing_channel.save()
                else:
                    # 创建新的通知渠道
                    NotificationChannel.objects.create(
                        name=channel_name,
                        channel_type='email',
                        config=config_data,
                        is_active=email_config.is_active
                    )

        except Exception as e:
            logger.error(f"同步邮件配置到通知渠道失败: {e}")

    def destroy(self, request, *args, **kwargs):
        """删除通知渠道"""
        try:
            channel = self.get_object()
            channel_name = channel.name
            channel_id = channel.id

            # 检查是否是从邮件配置同步的渠道
            email_config_id = channel.config.get('email_config_id') if channel.config else None

            if email_config_id:
                # 如果是从邮件配置同步的渠道，需要删除对应的邮件配置
                from .models import EmailConfig
                try:
                    email_config = EmailConfig.objects.get(id=email_config_id)
                    email_config.delete()
                    logger.info(f"删除邮件配置: {email_config.name} (ID: {email_config_id})")
                except EmailConfig.DoesNotExist:
                    logger.warning(f"邮件配置ID {email_config_id} 不存在")

            # 删除通知渠道
            channel.delete()
            logger.info(f"通知渠道删除成功: {channel_name} (ID: {channel_id})")

            return Response({
                'success': True,
                'message': '通知渠道删除成功'
            }, status=status.HTTP_200_OK)

        except Exception as e:
            logger.error(f"删除通知渠道失败: {e}")
            return Response({
                'success': False,
                'message': f'删除通知渠道失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['post'])
    def test_channel(self, request, pk=None):
        """测试通知渠道"""
        try:
            channel = self.get_object()
            logger.info(f"开始测试通知渠道: {channel.name}, 类型: {channel.channel_type}")

            # 创建测试通知
            from .utils.notification_service import NotificationService
            notification_service = NotificationService()

            # 发送测试通知
            try:
                # 生成测试通知内容
                subject = "[测试告警] DevOps监控系统测试"
                content = f"""
告警主机: test-host
告警级别: warning
告警状态: active
告警时间: {timezone.now()}
告警描述: 这是一个测试告警，用于验证通知渠道配置是否正确。
监控服务器: 测试服务器

这是一个测试通知，用于验证通知渠道配置是否正确。
"""

                # 根据渠道类型发送测试通知
                logger.info(f"渠道类型判断: {channel.channel_type}")
                if channel.channel_type == 'email':
                    logger.info("调用 _send_test_email 方法")
                    self._send_test_email(channel, subject, content)
                elif channel.channel_type == 'sms':
                    self._send_test_sms(channel, content)
                elif channel.channel_type == 'webhook':
                    self._send_test_webhook(channel, subject, content)
                elif channel.channel_type == 'dingtalk':
                    self._send_test_dingtalk(channel, subject, content)
                elif channel.channel_type == 'wechat':
                    self._send_test_wechat(channel, subject, content)
                elif channel.channel_type == 'slack':
                    self._send_test_slack(channel, subject, content)
                else:
                    return Response({
                        'success': False,
                        'message': f'不支持的通知渠道类型: {channel.channel_type}'
                    }, status=status.HTTP_400_BAD_REQUEST)

                return Response({
                    'success': True,
                    'message': '测试通知发送成功'
                })
            except Exception as e:
                return Response({
                    'success': False,
                    'message': f'测试通知发送失败: {str(e)}'
                }, status=status.HTTP_400_BAD_REQUEST)

        except Exception as e:
            logger.error(f"测试通知渠道失败: {e}")
            return Response({
                'success': False,
                'message': f'测试失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    def _send_test_email(self, channel, subject, content):
        """发送测试邮件"""
        import smtplib
        from email.mime.text import MIMEText
        from email.mime.multipart import MIMEMultipart
        from django.utils import timezone

        config = channel.config

        # 优先使用通知渠道的直接配置
        smtp_server = config.get('smtp_server')
        smtp_port = config.get('smtp_port', 587)
        username = config.get('username')
        password = config.get('password')
        from_email = config.get('from_email')
        use_ssl = config.get('use_ssl', False)
        use_tls = config.get('use_tls', True) if not use_ssl else False

        # 如果通知渠道没有完整的直接配置，再尝试使用邮件配置ID
        if not all([smtp_server, username, password, from_email]):
            email_config_id = config.get('email_config_id')
            if email_config_id:
                # 从EmailConfig表获取配置
                from .models import EmailConfig
                try:
                    email_config = EmailConfig.objects.get(id=email_config_id, is_active=True)
                    smtp_server = email_config.smtp_server
                    smtp_port = email_config.smtp_port
                    username = email_config.username
                    password = email_config.password
                    from_email = email_config.from_email
                    use_tls = email_config.use_tls
                    use_ssl = email_config.use_ssl
                except EmailConfig.DoesNotExist:
                    raise ValueError(f"邮件配置ID {email_config_id} 不存在，且通知渠道配置不完整")

        # 获取收件人列表
        recipients = config.get('recipients', [])
        if not recipients:
            recipients = [from_email]  # 如果没有收件人，发送给自己

        # 验证必要字段
        if not all([smtp_server, username, password, from_email]):
            raise ValueError("邮件配置不完整，请检查SMTP服务器、用户名、密码和发件人邮箱设置")

        logger.info(f"邮件配置验证通过: SMTP={smtp_server}:{smtp_port}, 用户={username}, 发件人={from_email}")
        logger.info(f"收件人列表: {recipients}")
        logger.info(f"加密设置: SSL={use_ssl}, TLS={use_tls}")

        # HTML邮件内容 - 完全照搬EmailConfigViewSet的样式
        html_content = f"""
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <style>
        body {{
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            margin: 0;
            padding: 20px;
        }}
        .container {{
            max-width: 600px;
            margin: 0 auto;
            background: rgba(255, 255, 255, 0.95);
            border-radius: 15px;
            box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
            overflow: hidden;
            backdrop-filter: blur(10px);
        }}
        .header {{
            background: linear-gradient(135deg, #a4f4ba 0%, #22c55e 100%);
            color: white;
            padding: 30px;
            text-align: center;
        }}
        .header h1 {{
            margin: 0;
            font-size: 28px;
            font-weight: 600;
            text-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
        }}
        .header .icon {{
            font-size: 48px;
            margin-bottom: 10px;
        }}
        .content {{
            padding: 40px;
        }}
        .success-badge {{
            background: linear-gradient(135deg, #22c55e, #16a34a);
            color: white;
            padding: 15px 25px;
            border-radius: 50px;
            display: inline-block;
            font-weight: 600;
            margin-bottom: 30px;
            box-shadow: 0 4px 15px rgba(34, 197, 94, 0.3);
        }}
        .config-info {{
            background: #f8fafc;
            border-radius: 12px;
            padding: 25px;
            margin: 20px 0;
            border-left: 4px solid #a4f4ba;
        }}
        .config-item {{
            display: flex;
            justify-content: space-between;
            padding: 8px 0;
            border-bottom: 1px solid #e2e8f0;
        }}
        .config-item:last-child {{
            border-bottom: none;
        }}
        .config-label {{
            font-weight: 600;
            color: #475569;
        }}
        .config-value {{
            color: #1e293b;
            font-family: 'Courier New', monospace;
        }}
        .footer {{
            background: #f1f5f9;
            padding: 20px;
            text-align: center;
            color: #64748b;
            font-size: 14px;
        }}
        .timestamp {{
            background: linear-gradient(135deg, #667eea, #764ba2);
            color: white;
            padding: 10px 20px;
            border-radius: 25px;
            display: inline-block;
            margin-top: 20px;
            font-weight: 500;
        }}
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <div class="icon">🚀</div>
            <h1>DevOps监控系统</h1>
            <p style="margin: 10px 0 0 0; opacity: 0.9;">邮件配置测试</p>
        </div>

        <div class="content">
            <div class="success-badge">
                ✅ 邮件配置测试成功
            </div>

            <p style="font-size: 16px; line-height: 1.6; color: #334155;">
                恭喜！您的邮件配置已经成功通过测试。以下是当前配置的详细信息：
            </p>

            <div class="config-info">
                <h3 style="margin-top: 0; color: #1e293b;">📧 配置详情</h3>
                <div class="config-item">
                    <span class="config-label">配置名称:</span>
                    <span class="config-value">{channel.name}</span>
                </div>
                <div class="config-item">
                    <span class="config-label">SMTP服务器:</span>
                    <span class="config-value">{smtp_server}:{smtp_port}</span>
                </div>
                <div class="config-item">
                    <span class="config-label">发件人邮箱:</span>
                    <span class="config-value">{from_email}</span>
                </div>
                <div class="config-item">
                    <span class="config-label">收件人:</span>
                    <span class="config-value">{', '.join(recipients)}</span>
                </div>
                <div class="config-item">
                    <span class="config-label">加密方式:</span>
                    <span class="config-value">{'SSL' if use_ssl else ('TLS' if use_tls else '无加密')}</span>
                </div>
            </div>

            <p style="font-size: 14px; color: #64748b; line-height: 1.6;">
                💡 <strong>提示:</strong> 此邮件配置将用于发送系统告警通知。请确保收件人列表包含所有需要接收告警的人员。
            </p>

            <div class="timestamp">
                🕒 测试时间: {timezone.now().strftime('%Y-%m-%d %H:%M:%S')}
            </div>
        </div>

        <div class="footer">
            <p>此邮件由 DevOps 监控系统自动发送，请勿回复。</p>
            <p style="margin: 5px 0 0 0;">如有问题，请联系系统管理员。</p>
        </div>
    </div>
</body>
</html>
"""

        # 纯文本版本
        text_content = f"""
🚀 DevOps监控系统 - 邮件通知测试

✅ 邮件配置测试成功

恭喜！您的邮件通知渠道已经成功通过测试。

配置详情:
- 通知渠道: {channel.name}
- SMTP服务器: {smtp_server}:{smtp_port}
- 发件人邮箱: {from_email}
- 收件人: {', '.join(recipients)}
- 加密方式: {'SSL' if use_ssl else ('TLS' if use_tls else '无加密')}
- 测试时间: {timezone.now().strftime('%Y-%m-%d %H:%M:%S')}

{content}

此邮件由 DevOps 监控系统自动发送，请勿回复。
"""

        # 发送邮件
        server = None
        try:
            logger.info(f"尝试连接SMTP服务器: {smtp_server}:{smtp_port}, SSL={use_ssl}, TLS={use_tls}")

            # 建立连接
            if use_ssl:
                logger.info("使用SSL连接")
                server = smtplib.SMTP_SSL(smtp_server, smtp_port)
                logger.info("SSL连接建立成功")
            else:
                logger.info("使用普通SMTP连接")
                server = smtplib.SMTP(smtp_server, smtp_port)
                logger.info("SMTP连接建立成功")
                if use_tls:
                    logger.info("启用TLS加密")
                    server.starttls()
                    logger.info("TLS加密启用成功")

            # 登录 - QQ邮箱特殊处理
            logger.info(f"尝试登录用户: {username}")

            # QQ邮箱可能需要特殊的登录处理
            if 'qq.com' in smtp_server.lower():
                logger.info("检测到QQ邮箱，使用特殊登录处理")
                # QQ邮箱有时需要稍微延迟
                import time
                time.sleep(1)

            server.login(username, password)
            logger.info("SMTP登录成功")

            # 发送邮件
            for recipient in recipients:
                logger.info(f"准备发送邮件到: {recipient}")
                msg = MIMEMultipart('alternative')
                msg['From'] = from_email
                msg['To'] = recipient
                msg['Subject'] = subject

                # 先添加纯文本版本，再添加HTML版本（HTML优先显示）
                msg.attach(MIMEText(text_content, 'plain', 'utf-8'))
                msg.attach(MIMEText(html_content, 'html', 'utf-8'))

                server.send_message(msg)
                logger.info(f"邮件发送成功: {recipient}")

        except smtplib.SMTPAuthenticationError as e:
            error_msg = f"SMTP认证失败: {e}，请检查用户名和密码"
            logger.error(error_msg)
            raise ValueError(error_msg)
        except smtplib.SMTPConnectError as e:
            error_msg = f"SMTP连接失败: {e}，请检查服务器地址和端口"
            logger.error(error_msg)
            raise ValueError(error_msg)
        except smtplib.SMTPServerDisconnected as e:
            error_msg = f"SMTP服务器连接断开: {e}"
            logger.error(error_msg)
            # 针对QQ邮箱的特殊处理
            if 'qq.com' in smtp_server.lower():
                error_msg = "QQ邮箱连接被断开。请检查：1) 确保使用授权码而不是登录密码；2) 确保已开启POP3/SMTP服务；3) 避免频繁测试连接。获取授权码：QQ邮箱设置 -> 账户 -> POP3/IMAP/SMTP服务"
            raise ValueError(error_msg)
        except smtplib.SMTPException as e:
            error_msg = f"SMTP错误: {e}"
            logger.error(error_msg)
            raise ValueError(error_msg)
        except Exception as e:
            error_msg = f"邮件发送失败: {e}"
            logger.error(error_msg)
            raise ValueError(error_msg)
        finally:
            if server:
                try:
                    server.quit()
                    logger.info("SMTP连接已关闭")
                except Exception as e:
                    logger.warning(f"关闭SMTP连接时出错: {e}")

    def _send_test_sms(self, channel, content):
        """发送测试短信"""
        logger.info(f"短信测试发送: {content}")

    def _send_test_webhook(self, channel, subject, content):
        """发送测试Webhook"""
        logger.info(f"Webhook测试发送: {subject}")

    def _send_test_dingtalk(self, channel, subject, content):
        """发送测试钉钉消息"""
        logger.info(f"钉钉测试消息发送: {subject}")
        from .utils.notification_service import NotificationService
        notification_service = NotificationService()
        notification_service._send_dingtalk_test(channel, subject, content)

    def _send_test_wechat(self, channel, subject, content):
        """发送测试企业微信消息"""
        logger.info(f"企业微信测试消息发送: {subject}")
        from .utils.notification_service import NotificationService
        notification_service = NotificationService()
        notification_service._send_wechat_test(channel, subject, content)

    def _send_test_slack(self, channel, subject, content):
        """发送测试Slack消息"""
        logger.info(f"Slack测试消息发送: {subject}")


class EmailConfigViewSet(viewsets.ModelViewSet):
    """邮件配置管理"""
    queryset = EmailConfig.objects.all()
    serializer_class = EmailConfigSerializer
    permission_classes = [IsAuthenticated]

    def perform_create(self, serializer):
        serializer.save(created_by=self.request.user)

    @action(detail=True, methods=['post'])
    def test_config(self, request, pk=None):
        """测试邮件配置"""
        try:
            config = self.get_object()

            # 发送测试邮件
            import smtplib
            from email.mime.text import MIMEText
            from email.mime.multipart import MIMEMultipart

            # 确定收件人
            recipients = config.default_recipients.strip() if config.default_recipients else config.from_email
            if not recipients:
                recipients = config.from_email

            msg = MIMEMultipart('alternative')
            msg['From'] = config.from_email
            msg['To'] = recipients
            msg['Subject'] = "🚀 DevOps监控系统 - 邮件配置测试"

            # HTML邮件内容
            html_content = f"""
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <style>
        body {{
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            margin: 0;
            padding: 20px;
        }}
        .container {{
            max-width: 600px;
            margin: 0 auto;
            background: rgba(255, 255, 255, 0.95);
            border-radius: 15px;
            box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
            overflow: hidden;
            backdrop-filter: blur(10px);
        }}
        .header {{
            background: linear-gradient(135deg, #a4f4ba 0%, #22c55e 100%);
            color: white;
            padding: 30px;
            text-align: center;
        }}
        .header h1 {{
            margin: 0;
            font-size: 28px;
            font-weight: 600;
            text-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
        }}
        .header .icon {{
            font-size: 48px;
            margin-bottom: 10px;
        }}
        .content {{
            padding: 40px;
        }}
        .success-badge {{
            background: linear-gradient(135deg, #22c55e, #16a34a);
            color: white;
            padding: 15px 25px;
            border-radius: 50px;
            display: inline-block;
            font-weight: 600;
            margin-bottom: 30px;
            box-shadow: 0 4px 15px rgba(34, 197, 94, 0.3);
        }}
        .config-info {{
            background: #f8fafc;
            border-radius: 12px;
            padding: 25px;
            margin: 20px 0;
            border-left: 4px solid #a4f4ba;
        }}
        .config-item {{
            display: flex;
            justify-content: space-between;
            padding: 8px 0;
            border-bottom: 1px solid #e2e8f0;
        }}
        .config-item:last-child {{
            border-bottom: none;
        }}
        .config-label {{
            font-weight: 600;
            color: #475569;
        }}
        .config-value {{
            color: #1e293b;
            font-family: 'Courier New', monospace;
        }}
        .footer {{
            background: #f1f5f9;
            padding: 20px;
            text-align: center;
            color: #64748b;
            font-size: 14px;
        }}
        .timestamp {{
            background: linear-gradient(135deg, #667eea, #764ba2);
            color: white;
            padding: 10px 20px;
            border-radius: 25px;
            display: inline-block;
            margin-top: 20px;
            font-weight: 500;
        }}
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <div class="icon">🚀</div>
            <h1>DevOps监控系统</h1>
            <p style="margin: 10px 0 0 0; opacity: 0.9;">邮件配置测试</p>
        </div>

        <div class="content">
            <div class="success-badge">
                ✅ 邮件配置测试成功
            </div>

            <p style="font-size: 16px; line-height: 1.6; color: #334155;">
                恭喜！您的邮件配置已经成功通过测试。以下是当前配置的详细信息：
            </p>

            <div class="config-info">
                <h3 style="margin-top: 0; color: #1e293b;">📧 配置详情</h3>
                <div class="config-item">
                    <span class="config-label">配置名称:</span>
                    <span class="config-value">{config.name}</span>
                </div>
                <div class="config-item">
                    <span class="config-label">SMTP服务器:</span>
                    <span class="config-value">{config.smtp_server}:{config.smtp_port}</span>
                </div>
                <div class="config-item">
                    <span class="config-label">发件人邮箱:</span>
                    <span class="config-value">{config.from_email}</span>
                </div>
                <div class="config-item">
                    <span class="config-label">收件人:</span>
                    <span class="config-value">{recipients}</span>
                </div>
                <div class="config-item">
                    <span class="config-label">加密方式:</span>
                    <span class="config-value">{'TLS' if config.use_tls else ('SSL' if config.use_ssl else '无加密')}</span>
                </div>
                <div class="config-item">
                    <span class="config-label">默认配置:</span>
                    <span class="config-value">{'是' if config.is_default else '否'}</span>
                </div>
            </div>

            <p style="font-size: 14px; color: #64748b; line-height: 1.6;">
                💡 <strong>提示:</strong> 此邮件配置将用于发送系统告警通知。请确保收件人列表包含所有需要接收告警的人员。
            </p>

            <div class="timestamp">
                🕒 测试时间: {timezone.now().strftime('%Y-%m-%d %H:%M:%S')}
            </div>
        </div>

        <div class="footer">
            <p>此邮件由 DevOps 监控系统自动发送，请勿回复。</p>
            <p style="margin: 5px 0 0 0;">如有问题，请联系系统管理员。</p>
        </div>
    </div>
</body>
</html>
"""

            # 纯文本版本（备用）
            text_content = f"""
DevOps监控系统 - 邮件配置测试

✅ 邮件配置测试成功

恭喜！您的邮件配置已经成功通过测试。

配置详情:
- 配置名称: {config.name}
- SMTP服务器: {config.smtp_server}:{config.smtp_port}
- 发件人邮箱: {config.from_email}
- 收件人: {recipients}
- 加密方式: {'TLS' if config.use_tls else ('SSL' if config.use_ssl else '无加密')}
- 默认配置: {'是' if config.is_default else '否'}

测试时间: {timezone.now().strftime('%Y-%m-%d %H:%M:%S')}

此邮件由 DevOps 监控系统自动发送，请勿回复。
"""

            # 添加HTML和文本版本
            msg.attach(MIMEText(text_content, 'plain', 'utf-8'))
            msg.attach(MIMEText(html_content, 'html', 'utf-8'))

            # 发送邮件
            server = None
            try:
                logger.info(f"尝试连接SMTP服务器: {config.smtp_server}:{config.smtp_port}, SSL={config.use_ssl}, TLS={config.use_tls}")

                if config.use_ssl:
                    server = smtplib.SMTP_SSL(config.smtp_server, config.smtp_port)
                    logger.info("SSL连接建立成功")
                else:
                    server = smtplib.SMTP(config.smtp_server, config.smtp_port)
                    logger.info("SMTP连接建立成功")
                    if config.use_tls:
                        server.starttls()
                        logger.info("TLS加密启用成功")

                logger.info(f"尝试登录用户: {config.username}")
                try:
                    server.login(config.username, config.password)
                    logger.info("SMTP登录成功")
                except smtplib.SMTPAuthenticationError as e:
                    logger.error(f"SMTP认证失败: {e}")
                    if 'qq.com' in config.smtp_server.lower():
                        raise Exception("QQ邮箱认证失败。请确保使用授权码而不是登录密码。获取授权码：QQ邮箱设置 -> 账户 -> POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务 -> 生成授权码")
                    else:
                        raise Exception(f"邮箱认证失败: {e}")
                except Exception as e:
                    logger.error(f"SMTP登录异常: {e}")
                    error_msg = str(e).lower()
                    if 'connection unexpectedly closed' in error_msg:
                        if 'qq.com' in config.smtp_server.lower():
                            raise Exception("QQ邮箱连接被拒绝。请检查：1) 使用授权码而不是登录密码；2) 确保已开启POP3/SMTP服务。获取授权码：QQ邮箱设置 -> 账户 -> POP3/IMAP/SMTP服务")
                        else:
                            raise Exception(f"邮箱服务器拒绝连接，请检查用户名和密码: {e}")
                    else:
                        raise

                server.send_message(msg)
                logger.info("测试邮件发送成功")

            finally:
                if server:
                    try:
                        server.quit()
                    except Exception as e:
                        logger.warning(f"关闭SMTP连接时出错: {e}")

            return Response({
                'success': True,
                'message': '测试邮件发送成功，请检查收件箱'
            })

        except Exception as e:
            logger.error(f"测试邮件配置失败: {e}")
            return Response({
                'success': False,
                'message': f'测试失败: {str(e)}'
            }, status=status.HTTP_400_BAD_REQUEST)

    @action(detail=True, methods=['post'])
    def set_default(self, request, pk=None):
        """设置为默认配置"""
        try:
            config = self.get_object()

            # 取消其他默认配置
            EmailConfig.objects.filter(is_default=True).update(is_default=False)

            # 设置当前配置为默认
            config.is_default = True
            config.save()

            return Response({
                'success': True,
                'message': '已设置为默认邮件配置'
            })

        except Exception as e:
            logger.error(f"设置默认邮件配置失败: {e}")
            return Response({
                'success': False,
                'message': f'设置失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    def destroy(self, request, *args, **kwargs):
        """删除邮件配置"""
        instance = self.get_object()
        was_default = instance.is_default

        # 执行删除
        response = super().destroy(request, *args, **kwargs)

        # 如果删除的是默认配置，自动设置剩余的第一个配置为默认
        if was_default:
            remaining_config = EmailConfig.objects.filter(is_active=True).first()
            if remaining_config:
                remaining_config.is_default = True
                remaining_config.save()

        return response


class AlertNotificationViewSet(viewsets.ReadOnlyModelViewSet):
    """告警通知记录管理（只读）"""
    queryset = AlertNotification.objects.all()
    serializer_class = AlertNotificationSerializer
    permission_classes = [IsAuthenticated]

    def get_queryset(self):
        queryset = super().get_queryset()

        # 过滤参数
        alert_id = self.request.query_params.get('alert_id')
        channel_id = self.request.query_params.get('channel_id')
        status_filter = self.request.query_params.get('status')

        if alert_id:
            queryset = queryset.filter(alert_id=alert_id)
        if channel_id:
            queryset = queryset.filter(channel_id=channel_id)
        if status_filter:
            queryset = queryset.filter(status=status_filter)

        return queryset


# API视图函数
@api_view(['POST'])
@permission_classes([IsAuthenticated])
def sync_hosts_to_zabbix(request):
    """同步主机到Zabbix"""
    try:
        zabbix_server_id = request.data.get('zabbix_server_id')
        host_ids = request.data.get('host_ids')  # 可选：指定要同步的主机ID列表

        if not zabbix_server_id:
            return Response({
                'success': False,
                'message': '请指定Zabbix服务器ID'
            }, status=status.HTTP_400_BAD_REQUEST)

        try:
            zabbix_server = ZabbixServer.objects.get(id=zabbix_server_id, is_active=True)
        except ZabbixServer.DoesNotExist:
            return Response({
                'success': False,
                'message': 'Zabbix服务器不存在或已禁用'
            }, status=status.HTTP_404_NOT_FOUND)

        # 使用同步服务
        from .utils.sync_service import CMDBZabbixSyncService
        sync_service = CMDBZabbixSyncService(zabbix_server)
        result = sync_service.sync_hosts_to_zabbix(host_ids)

        if result['success']:
            return Response(result)
        else:
            return Response({
                'success': False,
                'message': result.get('error', '同步失败')
            }, status=status.HTTP_400_BAD_REQUEST)

    except Exception as e:
        logger.error(f"同步主机到Zabbix失败: {e}")
        return Response({
            'success': False,
            'message': f'同步失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def cleanup_monitoring_hosts(request):
    """清理监控主机数据并重新同步"""
    try:
        zabbix_server_id = request.data.get('zabbix_server_id')

        if not zabbix_server_id:
            return Response({
                'success': False,
                'message': '请指定Zabbix服务器ID'
            }, status=status.HTTP_400_BAD_REQUEST)

        try:
            zabbix_server = ZabbixServer.objects.get(id=zabbix_server_id)
        except ZabbixServer.DoesNotExist:
            return Response({
                'success': False,
                'message': '指定的Zabbix服务器不存在'
            }, status=status.HTTP_404_NOT_FOUND)

        logger.info(f"开始清理Zabbix服务器 {zabbix_server.name} 的监控主机数据")

        # 1. 清理Django数据库中的旧监控主机记录
        old_monitoring_hosts = MonitoringHost.objects.filter(zabbix_server=zabbix_server)
        old_count = old_monitoring_hosts.count()
        logger.info(f"找到 {old_count} 个旧的监控主机记录")

        old_monitoring_hosts.delete()
        logger.info(f"已删除 {old_count} 个旧的监控主机记录")

        # 2. 获取Zabbix中的实际主机列表
        from .utils.zabbix_api import ZabbixAPIManager
        api_manager = ZabbixAPIManager(zabbix_server)

        if not api_manager._connect():
            return Response({
                'success': False,
                'message': 'Zabbix API连接失败'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        # 获取Zabbix中的所有主机
        zabbix_hosts_result = api_manager.get_hosts()
        if not zabbix_hosts_result['success']:
            return Response({
                'success': False,
                'message': f'获取Zabbix主机列表失败: {zabbix_hosts_result.get("error", "未知错误")}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        zabbix_hosts = zabbix_hosts_result['data']
        logger.info(f"Zabbix中找到 {len(zabbix_hosts)} 个主机")

        # 3. 重新建立Django和Zabbix的关联
        from cmdb.models import Host
        matched_count = 0
        unmatched_zabbix_hosts = []

        for zabbix_host in zabbix_hosts:
            zabbix_host_name = zabbix_host.get('host', '')
            zabbix_host_id = zabbix_host.get('hostid', '')

            # 尝试通过主机名匹配CMDB中的主机
            try:
                cmdb_host = Host.objects.get(hostname=zabbix_host_name)

                # 创建新的监控主机记录
                monitoring_host = MonitoringHost.objects.create(
                    host=cmdb_host,
                    zabbix_server=zabbix_server,
                    zabbix_host_id=zabbix_host_id,
                    zabbix_host_name=zabbix_host_name,
                    monitoring_status='monitoring',
                    availability=zabbix_host.get('available', '0')
                )

                matched_count += 1
                logger.info(f"成功关联主机: {zabbix_host_name} (Zabbix ID: {zabbix_host_id})")

            except Host.DoesNotExist:
                unmatched_zabbix_hosts.append({
                    'hostname': zabbix_host_name,
                    'zabbix_id': zabbix_host_id
                })
                logger.warning(f"Zabbix主机 {zabbix_host_name} 在CMDB中未找到对应记录")

        return Response({
            'success': True,
            'message': '监控主机数据清理和重新同步完成',
            'data': {
                'deleted_old_records': old_count,
                'zabbix_hosts_found': len(zabbix_hosts),
                'matched_hosts': matched_count,
                'unmatched_hosts': len(unmatched_zabbix_hosts),
                'unmatched_details': unmatched_zabbix_hosts
            }
        })

    except Exception as e:
        logger.error(f"清理监控主机数据失败: {e}")
        import traceback
        logger.error(f"错误堆栈: {traceback.format_exc()}")
        return Response({
            'success': False,
            'message': f'清理失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def quick_associate_host(request):
    """
    快速关联主机
    将Zabbix中的未关联主机与CMDB中的主机进行自动匹配和关联
    """
    try:
        data = request.data
        zabbix_host_id = data.get('zabbix_host_id')
        zabbix_server_id = data.get('zabbix_server_id')
        hostname = data.get('hostname')

        if not zabbix_host_id or not zabbix_server_id:
            return Response({
                'success': False,
                'message': 'Zabbix主机ID和服务器ID不能为空'
            }, status=status.HTTP_400_BAD_REQUEST)

        # 获取Zabbix服务器
        try:
            zabbix_server = ZabbixServer.objects.get(id=zabbix_server_id)
        except ZabbixServer.DoesNotExist:
            return Response({
                'success': False,
                'message': 'Zabbix服务器不存在'
            }, status=status.HTTP_404_NOT_FOUND)

        # 检查是否已经关联
        existing_monitoring_host = MonitoringHost.objects.filter(
            zabbix_host_id=zabbix_host_id,
            zabbix_server=zabbix_server
        ).first()

        if existing_monitoring_host and existing_monitoring_host.host:
            return Response({
                'success': True,
                'message': f'主机 {hostname} 已经关联到CMDB主机 {existing_monitoring_host.host.hostname}'
            })

        # 尝试通过主机名匹配CMDB主机
        from cmdb.models import Host
        from django.db import models
        cmdb_host = None

        try:
            # 首先尝试精确匹配主机名
            cmdb_host = Host.objects.get(hostname=hostname)
        except Host.DoesNotExist:
            # 如果精确匹配失败，尝试通过IP地址匹配
            from .utils.zabbix_api import ZabbixAPIManager
            api_manager = ZabbixAPIManager(zabbix_server)

            if api_manager._connect():
                # 获取Zabbix主机的接口信息
                hosts_result = api_manager.get_hosts(hostids=[zabbix_host_id])
                if hosts_result['success'] and hosts_result['data']:
                    zabbix_host = hosts_result['data'][0]
                    interfaces = zabbix_host.get('interfaces', [])

                    # 尝试通过IP地址匹配
                    for interface in interfaces:
                        ip_address = interface.get('ip')
                        if ip_address:
                            try:
                                cmdb_host = Host.objects.get(
                                    models.Q(private_ip=ip_address) | models.Q(public_ip=ip_address)
                                )
                                break
                            except Host.DoesNotExist:
                                continue

        if cmdb_host:
            # 创建或更新监控主机关联
            if existing_monitoring_host:
                existing_monitoring_host.host = cmdb_host
                existing_monitoring_host.zabbix_host_name = hostname
                existing_monitoring_host.monitoring_status = 'monitoring'
                existing_monitoring_host.save()
                monitoring_host = existing_monitoring_host
            else:
                monitoring_host = MonitoringHost.objects.create(
                    host=cmdb_host,
                    zabbix_server=zabbix_server,
                    zabbix_host_id=zabbix_host_id,
                    zabbix_host_name=hostname,
                    monitoring_status='monitoring'
                )

            logger.info(f"快速关联成功: Zabbix主机 {hostname} 关联到CMDB主机 {cmdb_host.hostname}")

            return Response({
                'success': True,
                'data': {
                    'zabbix_hostname': hostname,
                    'cmdb_hostname': cmdb_host.hostname,
                    'cmdb_host_id': cmdb_host.id
                },
                'message': f'主机 {hostname} 成功关联到CMDB主机 {cmdb_host.hostname}'
            })
        else:
            # 如果CMDB中没有找到匹配的主机，自动创建
            try:
                # 获取Zabbix主机的IP地址用于创建CMDB主机
                ip_address = None
                from .utils.zabbix_api import ZabbixAPIManager
                api_manager = ZabbixAPIManager(zabbix_server)

                if api_manager._connect():
                    hosts_result = api_manager.get_hosts(hostids=[zabbix_host_id])
                    if hosts_result['success'] and hosts_result['data']:
                        zabbix_host = hosts_result['data'][0]
                        interfaces = zabbix_host.get('interfaces', [])
                        if interfaces:
                            ip_address = interfaces[0].get('ip', '未知')

                # 创建新的CMDB主机记录
                cmdb_host = Host.objects.create(
                    hostname=hostname,
                    private_ip=ip_address or '127.0.0.1',
                    public_ip=ip_address or '127.0.0.1',  # 必填字段
                    username='root',  # 必填字段，默认值
                    os='Linux',  # 操作系统字段
                    status='offline',  # 状态字段
                    remark=f'通过Zabbix快速关联自动创建 - {hostname}'
                )

                # 创建监控主机关联
                if existing_monitoring_host:
                    existing_monitoring_host.host = cmdb_host
                    existing_monitoring_host.zabbix_host_name = hostname
                    existing_monitoring_host.monitoring_status = 'monitoring'
                    existing_monitoring_host.save()
                    monitoring_host = existing_monitoring_host
                else:
                    monitoring_host = MonitoringHost.objects.create(
                        host=cmdb_host,
                        zabbix_server=zabbix_server,
                        zabbix_host_id=zabbix_host_id,
                        zabbix_host_name=hostname,
                        monitoring_status='monitoring'
                    )

                logger.info(f"自动创建CMDB主机并关联成功: {hostname} ({ip_address})")

                return Response({
                    'success': True,
                    'data': {
                        'zabbix_hostname': hostname,
                        'cmdb_hostname': cmdb_host.hostname,
                        'cmdb_host_id': cmdb_host.id,
                        'created': True
                    },
                    'message': f'主机 {hostname} 已自动创建并关联成功'
                })

            except Exception as e:
                logger.error(f"自动创建CMDB主机失败: {e}")
                return Response({
                    'success': False,
                    'message': f'自动创建CMDB主机失败: {str(e)}'
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    except Exception as e:
        logger.error(f"快速关联主机失败: {e}")
        return Response({
            'success': False,
            'message': f'快速关联失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def sync_alerts_from_zabbix(request):
    """从Zabbix同步告警"""
    try:
        zabbix_server_id = request.data.get('zabbix_server_id')

        if not zabbix_server_id:
            return Response({
                'success': False,
                'message': '请指定Zabbix服务器ID'
            }, status=status.HTTP_400_BAD_REQUEST)

        try:
            zabbix_server = ZabbixServer.objects.get(id=zabbix_server_id, is_active=True)
        except ZabbixServer.DoesNotExist:
            return Response({
                'success': False,
                'message': 'Zabbix服务器不存在或已禁用'
            }, status=status.HTTP_404_NOT_FOUND)

        # 使用Zabbix API获取告警
        from .utils.zabbix_api import ZabbixAPIManager
        api_manager = ZabbixAPIManager(zabbix_server)
        result = api_manager.get_alerts()

        if not result['success']:
            return Response({
                'success': False,
                'message': result.get('error', '获取Zabbix告警失败')
            }, status=status.HTTP_400_BAD_REQUEST)

        alerts = result['data']
        sync_count = 0

        for alert in alerts:
            try:
                # 查找对应的监控主机
                monitoring_host = None
                if alert.get('hosts'):
                    hostname = alert['hosts'][0].get('host')
                    try:
                        monitoring_host = MonitoringHost.objects.get(zabbix_host_name=hostname)
                    except MonitoringHost.DoesNotExist:
                        pass

                # 映射Zabbix告警级别
                def map_zabbix_severity(severity):
                    severity_map = {
                        '0': 'low',      # Not classified
                        '1': 'low',      # Information
                        '2': 'low',      # Warning
                        '3': 'medium',   # Average
                        '4': 'high',     # High
                        '5': 'high'      # Disaster
                    }
                    return severity_map.get(str(severity), 'low')

                # 创建或更新告警记录
                alert_obj, created = MonitoringAlert.objects.get_or_create(
                    zabbix_event_id=alert.get('eventid'),
                    defaults={
                        'host': monitoring_host,
                        'alert_name': alert.get('name', '未知告警'),
                        'severity': map_zabbix_severity(alert.get('severity', '0')),
                        'status': 'active' if alert.get('r_eventid') == '0' else 'resolved',
                        'description': alert.get('name', ''),
                        'zabbix_server': zabbix_server,
                        'raw_data': alert
                    }
                )

                if created:
                    sync_count += 1

            except Exception as e:
                logger.warning(f"同步告警失败: {e}")
                continue

        return Response({
            'success': True,
            'data': {
                'total_alerts': len(alerts),
                'synced_count': sync_count
            },
            'message': f'同步完成，新增告警: {sync_count}'
        })

    except Exception as e:
        logger.error(f"从Zabbix同步告警失败: {e}")
        return Response({
            'success': False,
            'message': f'同步失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['GET'])
@permission_classes([IsAuthenticated])
def monitoring_overview(request):
    """监控概览"""
    try:
        # 统计数据
        total_zabbix_servers = ZabbixServer.objects.filter(is_active=True).count()
        total_grafana_servers = 0  # Grafana功能已移除
        total_monitored_hosts = MonitoringHost.objects.filter(monitoring_status='monitoring').count()
        total_active_alerts = MonitoringAlert.objects.filter(status='active').count()

        # 连接状态统计
        connected_zabbix = ZabbixServer.objects.filter(
            is_active=True, connection_status='connected'
        ).count()
        connected_grafana = 0  # Grafana功能已移除

        # 告警分级统计
        alert_stats = MonitoringAlert.objects.filter(status='active').values('severity').annotate(
            count=Count('id')
        )

        # 格式化告警统计 - 支持前端需要的格式
        alert_severity_stats = {
            'critical': 0,  # 紧急 (disaster)
            'high': 0,      # 严重 (high)
            'medium': 0,    # 一般 (average)
            'low': 0        # 轻微 (warning, information)
        }

        # 映射Zabbix告警级别到前端显示级别
        severity_mapping = {
            'disaster': 'critical',
            'high': 'high',
            'average': 'medium',
            'warning': 'low',
            'information': 'low',
            'not_classified': 'low'
        }

        for alert in alert_stats:
            zabbix_severity = alert['severity']
            frontend_severity = severity_mapping.get(zabbix_severity, 'low')
            alert_severity_stats[frontend_severity] += alert['count']

        # 主机状态统计
        host_status_stats = MonitoringHost.objects.values('monitoring_status').annotate(
            count=Count('id')
        )

        # 获取主机详细状态（从Zabbix实时获取）
        host_status_list = []
        try:
            # 获取活跃的Zabbix服务器
            active_zabbix = ZabbixServer.objects.filter(
                is_active=True, connection_status='connected'
            ).first()

            if active_zabbix:
                from .utils.zabbix_api import ZabbixAPIManager
                api_manager = ZabbixAPIManager(active_zabbix)

                # 获取主机状态
                hosts_result = api_manager._make_request('host.get', {
                    'output': ['hostid', 'host', 'name', 'status', 'available'],
                    'selectInterfaces': ['ip'],
                    'filter': {'status': '0'}  # 只获取启用的主机
                })

                if hosts_result and 'result' in hosts_result:
                    for host in hosts_result['result']:
                        ip_address = ''
                        if host.get('interfaces') and len(host['interfaces']) > 0:
                            ip_address = host['interfaces'][0].get('ip', '')

                        host_status_list.append({
                            'id': host['hostid'],
                            'hostname': host['host'],
                            'name': host.get('name', host['host']),
                            'ip_address': ip_address,
                            'availability': host.get('available', '0'),  # 0=未知, 1=可用, 2=不可用
                            'status': host.get('status', '0')  # 0=启用, 1=禁用
                        })
        except Exception as e:
            logger.warning(f"获取主机状态失败: {e}")

        return Response({
            'success': True,
            'data': {
                'servers': {
                    'zabbix_total': total_zabbix_servers,
                    'zabbix_connected': connected_zabbix,
                    'grafana_total': total_grafana_servers,
                    'grafana_connected': connected_grafana
                },
                'monitoring': {
                    'total_hosts': total_monitored_hosts,
                    'active_alerts': total_active_alerts,
                    'alert_severity': alert_severity_stats,
                    'host_status': list(host_status_stats)
                },
                'host_status': host_status_list  # 添加详细主机状态
            }
        })
    except Exception as e:
        logger.error(f"获取监控概览失败: {e}")
        return Response({
            'success': False,
            'message': f'获取监控概览失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def sync_monitoring_status_to_cmdb(request):
    """同步监控状态到CMDB"""
    try:
        zabbix_server_id = request.data.get('zabbix_server_id')

        if not zabbix_server_id:
            return Response({
                'success': False,
                'message': '请指定Zabbix服务器ID'
            }, status=status.HTTP_400_BAD_REQUEST)

        try:
            zabbix_server = ZabbixServer.objects.get(id=zabbix_server_id, is_active=True)
        except ZabbixServer.DoesNotExist:
            return Response({
                'success': False,
                'message': 'Zabbix服务器不存在或已禁用'
            }, status=status.HTTP_404_NOT_FOUND)

        # 使用同步服务
        from .utils.sync_service import CMDBZabbixSyncService
        sync_service = CMDBZabbixSyncService(zabbix_server)
        result = sync_service.sync_monitoring_status_to_cmdb()

        if result['success']:
            return Response(result)
        else:
            return Response({
                'success': False,
                'message': result.get('error', '同步失败')
            }, status=status.HTTP_400_BAD_REQUEST)

    except Exception as e:
        logger.error(f"同步监控状态到CMDB失败: {e}")
        return Response({
            'success': False,
            'message': f'同步失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['GET'])
@permission_classes([IsAuthenticated])
def host_monitoring_status(request):
    """主机监控状态 - 显示Zabbix中的所有主机"""
    try:
        logger.info("开始获取主机监控状态")

        # 获取指定的Zabbix服务器ID
        zabbix_server_id = request.GET.get('zabbix_server_id')
        logger.info(f"请求的Zabbix服务器ID: {zabbix_server_id}")

        if not zabbix_server_id:
            return Response({
                'success': False,
                'message': '请指定Zabbix服务器ID'
            }, status=status.HTTP_400_BAD_REQUEST)

        # 获取Zabbix服务器
        try:
            zabbix_server = ZabbixServer.objects.get(id=zabbix_server_id)
        except ZabbixServer.DoesNotExist:
            return Response({
                'success': False,
                'message': '指定的Zabbix服务器不存在'
            }, status=status.HTTP_404_NOT_FOUND)

        # 连接Zabbix API
        from .utils.zabbix_api import ZabbixAPIManager
        api_manager = ZabbixAPIManager(zabbix_server)
        if not api_manager._connect():
            return Response({
                'success': False,
                'message': 'Zabbix服务器连接失败'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        # 直接从Zabbix获取所有主机
        hosts_result = api_manager.get_hosts()
        if not hosts_result['success']:
            return Response({
                'success': False,
                'message': f'获取Zabbix主机失败: {hosts_result.get("error")}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        zabbix_hosts = hosts_result['data']
        logger.info(f"从Zabbix获取到 {len(zabbix_hosts)} 个主机")

        # 获取已存在的监控主机记录（用于关联CMDB数据）
        existing_monitoring_hosts = {
            mh.zabbix_host_id: mh for mh in
            MonitoringHost.objects.select_related('host', 'zabbix_server').filter(
                zabbix_server=zabbix_server
            )
        }

        # 处理每个Zabbix主机
        host_data = []
        for i, zabbix_host in enumerate(zabbix_hosts):
            try:
                zabbix_host_id = zabbix_host['hostid']
                hostname = zabbix_host['host']

                logger.info(f"处理第 {i+1} 个Zabbix主机: {hostname} (ID: {zabbix_host_id})")

                # 基本主机信息
                host_info = {
                    'id': f"zabbix_{zabbix_host_id}",  # 使用Zabbix ID作为唯一标识
                    'hostname': hostname,
                    'ip_address': '',
                    'monitoring_status': 'monitoring',
                    'availability': zabbix_host.get('available', '0'),
                    'last_check_time': None,
                    'zabbix_host_id': zabbix_host_id,
                    'zabbix_server_name': zabbix_server.name,
                    'status': 'online' if zabbix_host.get('available') == '1' else 'offline',
                    'zabbix_data': zabbix_host
                }

                # 获取主机接口信息（IP地址）
                if zabbix_host.get('interfaces'):
                    interface = zabbix_host['interfaces'][0]
                    host_info['ip_address'] = interface.get('ip', '')

                # 检查是否有对应的CMDB主机记录
                monitoring_host = existing_monitoring_hosts.get(zabbix_host_id)
                if monitoring_host and monitoring_host.host:
                    # 有CMDB关联，使用CMDB数据补充信息
                    cmdb_host = monitoring_host.host
                    host_info.update({
                        'id': monitoring_host.id,  # 使用监控主机ID
                        'hostname': cmdb_host.hostname,  # 使用CMDB主机名
                        'ip_address': cmdb_host.private_ip or cmdb_host.public_ip or host_info['ip_address'],
                        'last_check_time': monitoring_host.last_check_time.isoformat() if monitoring_host.last_check_time else None,
                        'cmdb_linked': True,
                        'cmdb_host_id': cmdb_host.id  # 添加CMDB主机ID
                    })
                else:
                    # 没有CMDB关联
                    host_info['cmdb_linked'] = False
                    host_info['cmdb_host_id'] = None

                # 获取监控指标数据
                try:
                    metrics = api_manager.get_host_metrics(zabbix_host_id)
                    if metrics['success']:
                        host_info['monitoring_metrics'] = metrics['data']
                        # 展开主要监控指标到根级别
                        metrics_data = metrics['data']
                        host_info.update({
                            'cpu_usage': metrics_data.get('cpu_usage'),
                            'memory_usage': metrics_data.get('memory_usage'),
                            'disk_usage': metrics_data.get('disk_usage'),
                            'network_in': metrics_data.get('network_in'),
                            'network_out': metrics_data.get('network_out'),
                            'load_average': metrics_data.get('load_average')
                        })
                        logger.info(f"获取主机 {hostname} 监控指标成功")
                    else:
                        logger.warning(f"获取主机 {hostname} 监控指标失败: {metrics.get('error', '未知错误')}")
                except Exception as metrics_error:
                    logger.warning(f"获取主机 {hostname} 监控指标异常: {metrics_error}")

                host_data.append(host_info)
            except Exception as e:
                logger.error(f"处理Zabbix主机 {zabbix_host.get('host', 'unknown')} 时出错: {e}")
                continue

        # 统计信息
        total_hosts = len(host_data)
        online_hosts = len([h for h in host_data if h['status'] == 'online'])
        offline_hosts = len([h for h in host_data if h['status'] == 'offline'])
        unknown_hosts = len([h for h in host_data if h['status'] == 'unknown'])

        # 计算告警主机数量
        alert_hosts = 0
        try:
            # 获取有活跃告警的主机ID列表
            alert_host_ids = MonitoringAlert.objects.filter(
                status='active',
                zabbix_server=zabbix_server
            ).values_list('host_id', flat=True).distinct()

            # 计算有告警的主机数量
            alert_hosts = len([h for h in host_data if h.get('cmdb_host_id') in alert_host_ids])
        except Exception as e:
            logger.warning(f"计算告警主机数量失败: {e}")

        logger.info(f"主机统计 - 总计: {total_hosts}, 在线: {online_hosts}, 离线: {offline_hosts}, 未知: {unknown_hosts}, 告警: {alert_hosts}")

        return Response({
            'success': True,
            'data': {
                'hosts': host_data,
                'statistics': {
                    'total': total_hosts,
                    'online': online_hosts,
                    'offline': offline_hosts,
                    'unknown': unknown_hosts,
                    'alert_hosts': alert_hosts
                }
            }
        })

    except Exception as e:
        import traceback
        logger.error(f"获取主机监控状态失败: {e}")
        logger.error(f"错误堆栈: {traceback.format_exc()}")
        return Response({
            'success': False,
            'message': f'获取主机监控状态失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['GET'])
@permission_classes([IsAuthenticated])
def get_host_detailed_metrics(request, host_id):
    """获取主机详细监控指标"""
    try:
        logger.info(f"获取主机 {host_id} 的详细监控指标")

        # 获取指定的Zabbix服务器ID
        zabbix_server_id = request.GET.get('zabbix_server_id')
        logger.info(f"请求的Zabbix服务器ID: {zabbix_server_id}")

        # 查找对应的监控主机
        try:
            monitoring_host_query = MonitoringHost.objects.select_related('host', 'zabbix_server').filter(
                zabbix_host_id=host_id
            )

            # 如果指定了Zabbix服务器ID，则进一步过滤
            if zabbix_server_id:
                monitoring_host_query = monitoring_host_query.filter(zabbix_server_id=zabbix_server_id)

            monitoring_host = monitoring_host_query.first()

            # 对于未关联的主机（如zabbix_XXXXX格式），monitoring_host可能为None
            # 这是正常情况，我们将直接使用Zabbix API
            if not monitoring_host and not host_id.startswith('zabbix_'):
                return Response({
                    'success': False,
                    'message': '未找到对应的监控主机'
                }, status=status.HTTP_404_NOT_FOUND)

        except Exception as e:
            logger.error(f"查找监控主机失败: {e}")
            return Response({
                'success': False,
                'message': '查找监控主机失败'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        # 确定使用的Zabbix服务器
        if monitoring_host:
            if not monitoring_host.zabbix_server:
                return Response({
                    'success': False,
                    'message': '该主机未配置Zabbix服务器'
                }, status=status.HTTP_400_BAD_REQUEST)
            zabbix_server = monitoring_host.zabbix_server
        else:
            # 未关联主机，使用指定的Zabbix服务器
            pass  # zabbix_server 已在上面设置

        # 使用Zabbix API获取详细监控指标
        from .utils.zabbix_api import ZabbixAPIManager
        api_manager = ZabbixAPIManager(zabbix_server)

        logger.info(f"获取主机 {host_id} 的详细监控指标")

        # 连接到Zabbix API
        if not api_manager._connect():
            logger.error(f"Zabbix API连接失败")
            return Response({
                'success': False,
                'message': 'Zabbix API连接失败'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        logger.info(f"Zabbix API连接成功，api_manager.zapi: {api_manager.zapi}")

        # 获取主机的所有监控项
        items_result = api_manager.zapi.item.get(
            hostids=[host_id],
            output=['itemid', 'key_', 'name', 'lastvalue', 'units', 'description', 'value_type'],
            filter={'status': '0'},  # 只获取启用的监控项
            sortfield='name'
        )

        if not items_result:
            return Response({
                'success': False,
                'message': '获取监控项失败'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        # 智能分类和处理监控指标
        categorized_metrics = {
            'system': {'name': '系统指标', 'items': []},
            'cpu': {'name': 'CPU指标', 'items': []},
            'memory': {'name': '内存指标', 'items': []},
            'disk': {'name': '磁盘指标', 'items': []},
            'network': {'name': '网络指标', 'items': []},
            'process': {'name': '进程指标', 'items': []},
            'application': {'name': '应用指标', 'items': []},
            'other': {'name': '其他指标', 'items': []}
        }

        for item in items_result:
            key = item.get('key_', '').lower()
            name = item.get('name', '')
            value = item.get('lastvalue', '')
            units = item.get('units', '')
            description = item.get('description', '')

            # 跳过空值
            if not value or value == '':
                continue

            # 格式化数值
            formatted_value = _format_metric_value(value, units, key)

            metric_item = {
                'key': item.get('key_', ''),
                'name': name,
                'value': formatted_value,
                'raw_value': value,
                'units': units,
                'description': description,
                'category': _categorize_metric(key, name)
            }

            # 根据分类添加到对应类别
            category = metric_item['category']
            if category in categorized_metrics:
                categorized_metrics[category]['items'].append(metric_item)
            else:
                categorized_metrics['other']['items'].append(metric_item)

        # 移除空分类
        filtered_metrics = {k: v for k, v in categorized_metrics.items() if v['items']}

        # 获取主机基本信息
        host_info = {
            'hostname': monitoring_host.host.hostname,
            'ip_address': monitoring_host.host.private_ip or monitoring_host.host.public_ip,
            'zabbix_host_id': monitoring_host.zabbix_host_id,
            'zabbix_server_name': monitoring_host.zabbix_server.name,
            'monitoring_status': monitoring_host.monitoring_status,
            'last_check_time': monitoring_host.last_check_time.isoformat() if monitoring_host.last_check_time else None
        }

        return Response({
            'success': True,
            'data': {
                'host_info': host_info,
                'metrics': filtered_metrics,
                'total_items': len([item for category in filtered_metrics.values() for item in category['items']])
            }
        })

    except Exception as e:
        logger.error(f"获取主机详细监控指标失败: {e}")
        import traceback
        logger.error(f"错误堆栈: {traceback.format_exc()}")
        return Response({
            'success': False,
            'message': f'获取监控指标失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['GET', 'PUT'])
@permission_classes([IsAuthenticated])
def host_configuration(request, host_id):
    """主机配置管理"""
    try:
        logger.info(f"主机配置管理 - 主机ID: {host_id}, 方法: {request.method}")

        # 获取指定的Zabbix服务器ID
        zabbix_server_id = request.GET.get('zabbix_server_id') or request.data.get('zabbix_server_id')
        logger.info(f"请求的Zabbix服务器ID: {zabbix_server_id}")

        # 处理特殊格式的主机ID（如 zabbix_10084）
        actual_zabbix_host_id = host_id
        if host_id.startswith('zabbix_'):
            actual_zabbix_host_id = host_id.replace('zabbix_', '')
            logger.info(f"检测到特殊格式主机ID，转换为: {actual_zabbix_host_id}")

        # 查找对应的监控主机
        monitoring_host = None
        try:
            monitoring_host_query = MonitoringHost.objects.select_related('host', 'zabbix_server').filter(
                zabbix_host_id=actual_zabbix_host_id
            )

            if zabbix_server_id:
                monitoring_host_query = monitoring_host_query.filter(zabbix_server_id=zabbix_server_id)

            monitoring_host = monitoring_host_query.first()
            logger.info(f"查找到的监控主机: {monitoring_host}")

        except Exception as e:
            logger.error(f"查找监控主机失败: {e}")
            # 对于未关联主机，不返回错误，继续处理

        # 如果没有找到监控主机记录，说明是未关联的主机
        # 需要直接使用Zabbix API，但需要指定Zabbix服务器
        if not monitoring_host:
            if not zabbix_server_id:
                return Response({
                    'success': False,
                    'message': '未关联主机需要指定Zabbix服务器ID'
                }, status=status.HTTP_400_BAD_REQUEST)

            try:
                zabbix_server = ZabbixServer.objects.get(id=zabbix_server_id, is_active=True)
            except ZabbixServer.DoesNotExist:
                return Response({
                    'success': False,
                    'message': 'Zabbix服务器不存在或已禁用'
                }, status=status.HTTP_404_NOT_FOUND)

        # 确定使用的Zabbix服务器
        if monitoring_host:
            # 已关联主机，使用其配置的Zabbix服务器
            if not monitoring_host.zabbix_server:
                return Response({
                    'success': False,
                    'message': '该主机未配置Zabbix服务器'
                }, status=status.HTTP_400_BAD_REQUEST)
            zabbix_server = monitoring_host.zabbix_server
        else:
            # 未关联主机，使用指定的Zabbix服务器
            zabbix_server = ZabbixServer.objects.get(id=zabbix_server_id, is_active=True)

        # 使用Zabbix API
        from .utils.zabbix_api import ZabbixAPIManager
        api_manager = ZabbixAPIManager(zabbix_server)

        # 连接到Zabbix API
        if not api_manager._connect():
            logger.error(f"Zabbix API连接失败")
            return Response({
                'success': False,
                'message': 'Zabbix API连接失败'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        if request.method == 'GET':
            # 获取主机配置信息
            logger.info(f"获取主机 {actual_zabbix_host_id} 的配置信息")

            # 获取主机基本信息
            host_result = api_manager.zapi.host.get(
                hostids=[actual_zabbix_host_id],
                output=['hostid', 'host', 'name', 'description', 'status'],
                selectParentTemplates=['templateid', 'name', 'description'],
                selectGroups=['groupid', 'name'],
                selectInterfaces=['interfaceid', 'type', 'main', 'useip', 'ip', 'dns', 'port'],
                selectMacros=['macro', 'value', 'description']
            )

            if not host_result:
                return Response({
                    'success': False,
                    'message': '未找到主机信息'
                }, status=status.HTTP_404_NOT_FOUND)

            host_data = host_result[0]

            return Response({
                'success': True,
                'data': {
                    'host': host_data.get('host', ''),
                    'name': host_data.get('name', ''),
                    'description': host_data.get('description', ''),
                    'status': int(host_data.get('status', 0)),
                    'templates': host_data.get('parentTemplates', []),
                    'hostgroups': host_data.get('groups', []),
                    'interfaces': host_data.get('interfaces', []),
                    'macros': host_data.get('macros', [])
                }
            })

        elif request.method == 'PUT':
            # 更新主机配置
            logger.info(f"更新主机 {host_id} 的配置信息")

            config_data = request.data
            update_params = {
                'hostid': host_id
            }

            # 更新基本信息
            if 'basic' in config_data:
                basic = config_data['basic']
                if 'host' in basic:
                    update_params['host'] = basic['host']
                if 'name' in basic:
                    update_params['name'] = basic['name']
                if 'description' in basic:
                    update_params['description'] = basic['description']
                if 'status' in basic:
                    update_params['status'] = basic['status']

            # 更新模板
            if 'templates' in config_data:
                templates = config_data['templates']
                update_params['templates'] = [{'templateid': t['templateid']} for t in templates]

            # 更新主机组
            if 'hostgroups' in config_data:
                hostgroups = config_data['hostgroups']
                update_params['groups'] = [{'groupid': g['groupid']} for g in hostgroups]

            # 执行更新
            try:
                result = api_manager.zapi.host.update(update_params)
                logger.info(f"主机配置更新结果: {result}")

                return Response({
                    'success': True,
                    'message': '主机配置更新成功',
                    'data': result
                })

            except Exception as e:
                error_msg = str(e)
                logger.error(f"更新主机配置失败: {e}")

                # 处理常见的Zabbix错误
                if 'already exists' in error_msg:
                    if 'inherited from another template' in error_msg:
                        # 这种情况下配置实际上是成功的，只是有重复项警告
                        logger.warning(f"模板添加成功但有重复项警告: {error_msg}")
                        return Response({
                            'success': True,
                            'message': '模板添加成功，但检测到重复的监控项（这是正常的，不影响功能）',
                            'warning': '部分监控项已存在于其他模板中'
                        })
                    else:
                        user_msg = '配置冲突：该配置项已存在，请检查是否有重复配置'
                        return Response({
                            'success': False,
                            'message': user_msg
                        }, status=status.HTTP_400_BAD_REQUEST)
                elif 'Cannot find host interface' in error_msg:
                    if 'snmptrap' in error_msg.lower() or 'snmp' in error_msg.lower():
                        user_msg = '接口缺失：新模板需要SNMP接口，但该主机未配置SNMP接口。请先在Zabbix中为该主机添加SNMP接口，或选择不需要SNMP的模板'
                    elif 'jmx' in error_msg.lower():
                        user_msg = '接口缺失：新模板需要JMX接口，但该主机未配置JMX接口。请先在Zabbix中为该主机添加JMX接口，或选择不需要JMX的模板'
                    elif 'ipmi' in error_msg.lower():
                        user_msg = '接口缺失：新模板需要IPMI接口，但该主机未配置IPMI接口。请先在Zabbix中为该主机添加IPMI接口，或选择不需要IPMI的模板'
                    else:
                        user_msg = '接口缺失：新模板需要特定类型的接口，但该主机未配置相应接口。请检查主机接口配置'

                    return Response({
                        'success': False,
                        'message': user_msg
                    }, status=status.HTTP_400_BAD_REQUEST)
                elif 'Invalid params' in error_msg:
                    user_msg = '配置参数无效，请检查输入的配置信息'
                    return Response({
                        'success': False,
                        'message': user_msg
                    }, status=status.HTTP_400_BAD_REQUEST)
                elif 'Permission denied' in error_msg:
                    user_msg = '权限不足，无法修改该主机配置'
                    return Response({
                        'success': False,
                        'message': user_msg
                    }, status=status.HTTP_400_BAD_REQUEST)
                else:
                    user_msg = f'更新主机配置失败: {error_msg}'
                    return Response({
                        'success': False,
                        'message': user_msg
                    }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    except Exception as e:
        logger.error(f"主机配置管理失败: {e}")
        import traceback
        logger.error(f"错误堆栈: {traceback.format_exc()}")
        return Response({
            'success': False,
            'message': f'主机配置管理失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['GET'])
@permission_classes([IsAuthenticated])
def available_templates(request):
    """获取可用模板列表"""
    try:
        zabbix_server_id = request.GET.get('zabbix_server_id')

        if not zabbix_server_id:
            return Response({
                'success': False,
                'message': '请指定Zabbix服务器ID'
            }, status=status.HTTP_400_BAD_REQUEST)

        try:
            zabbix_server = ZabbixServer.objects.get(id=zabbix_server_id)
        except ZabbixServer.DoesNotExist:
            return Response({
                'success': False,
                'message': '指定的Zabbix服务器不存在'
            }, status=status.HTTP_404_NOT_FOUND)

        from .utils.zabbix_api import ZabbixAPIManager
        api_manager = ZabbixAPIManager(zabbix_server)

        if not api_manager._connect():
            return Response({
                'success': False,
                'message': 'Zabbix API连接失败'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        # 获取所有模板
        templates = api_manager.zapi.template.get(
            output=['templateid', 'name', 'description'],
            sortfield='name'
        )

        return Response({
            'success': True,
            'data': templates
        })

    except Exception as e:
        logger.error(f"获取可用模板失败: {e}")
        return Response({
            'success': False,
            'message': f'获取可用模板失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['GET'])
@permission_classes([IsAuthenticated])
def available_hostgroups(request):
    """获取可用主机组列表"""
    try:
        zabbix_server_id = request.GET.get('zabbix_server_id')

        if not zabbix_server_id:
            return Response({
                'success': False,
                'message': '请指定Zabbix服务器ID'
            }, status=status.HTTP_400_BAD_REQUEST)

        try:
            zabbix_server = ZabbixServer.objects.get(id=zabbix_server_id)
        except ZabbixServer.DoesNotExist:
            return Response({
                'success': False,
                'message': '指定的Zabbix服务器不存在'
            }, status=status.HTTP_404_NOT_FOUND)

        from .utils.zabbix_api import ZabbixAPIManager
        api_manager = ZabbixAPIManager(zabbix_server)

        if not api_manager._connect():
            return Response({
                'success': False,
                'message': 'Zabbix API连接失败'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        # 获取所有主机组
        hostgroups = api_manager.zapi.hostgroup.get(
            output=['groupid', 'name'],
            sortfield='name'
        )

        return Response({
            'success': True,
            'data': hostgroups
        })

    except Exception as e:
        logger.error(f"获取可用主机组失败: {e}")
        return Response({
            'success': False,
            'message': f'获取可用主机组失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


def _categorize_metric(key: str, name: str) -> str:
    """智能分类监控指标"""
    key_lower = key.lower()
    name_lower = name.lower()

    # CPU相关
    if any(keyword in key_lower for keyword in ['cpu', 'processor']) or any(keyword in name_lower for keyword in ['cpu', '处理器', 'processor']):
        return 'cpu'

    # 内存相关
    if any(keyword in key_lower for keyword in ['memory', 'mem', 'vm.memory']) or any(keyword in name_lower for keyword in ['memory', '内存', 'mem']):
        return 'memory'

    # 磁盘相关
    if any(keyword in key_lower for keyword in ['disk', 'vfs.fs', 'vfs.dev', 'io']) or any(keyword in name_lower for keyword in ['disk', '磁盘', 'filesystem', '文件系统']):
        return 'disk'

    # 网络相关
    if any(keyword in key_lower for keyword in ['net.if', 'network', 'tcp', 'udp']) or any(keyword in name_lower for keyword in ['network', '网络', 'interface', '接口']):
        return 'network'

    # 进程相关
    if any(keyword in key_lower for keyword in ['proc', 'process']) or any(keyword in name_lower for keyword in ['process', '进程', 'proc']):
        return 'process'

    # 系统相关
    if any(keyword in key_lower for keyword in ['system', 'uptime', 'load', 'kernel']) or any(keyword in name_lower for keyword in ['system', '系统', 'uptime', 'load', '负载']):
        return 'system'

    # 应用相关
    if any(keyword in key_lower for keyword in ['service', 'application', 'app']) or any(keyword in name_lower for keyword in ['service', '服务', 'application', '应用']):
        return 'application'

    return 'other'


def _format_metric_value(value: str, units: str, key: str) -> str:
    """格式化监控指标值"""
    try:
        # 尝试转换为数字
        num_value = float(value)

        # 根据单位和key进行格式化
        if units == '%':
            return f"{num_value:.2f}%"
        elif units in ['B', 'bytes']:
            return _format_bytes(num_value)
        elif units in ['bps', 'Bps']:
            return _format_bytes_per_second(num_value)
        elif 'time' in key.lower() or 'uptime' in key.lower():
            return _format_time_duration(num_value)
        elif units == 's':
            return f"{num_value:.2f}秒"
        elif num_value == int(num_value):
            return str(int(num_value))
        else:
            return f"{num_value:.2f}"
    except ValueError:
        # 如果不是数字，直接返回原值
        return str(value)


def _format_bytes(bytes_value: float) -> str:
    """格式化字节数"""
    for unit in ['B', 'KB', 'MB', 'GB', 'TB']:
        if bytes_value < 1024.0:
            return f"{bytes_value:.2f} {unit}"
        bytes_value /= 1024.0
    return f"{bytes_value:.2f} PB"


def _format_bytes_per_second(bps_value: float) -> str:
    """格式化每秒字节数"""
    for unit in ['B/s', 'KB/s', 'MB/s', 'GB/s']:
        if bps_value < 1024.0:
            return f"{bps_value:.2f} {unit}"
        bps_value /= 1024.0
    return f"{bps_value:.2f} TB/s"


def _format_time_duration(seconds: float) -> str:
    """格式化时间长度"""
    if seconds < 60:
        return f"{seconds:.0f}秒"
    elif seconds < 3600:
        return f"{seconds/60:.1f}分钟"
    elif seconds < 86400:
        return f"{seconds/3600:.1f}小时"
    else:
        return f"{seconds/86400:.1f}天"





# 告警管理相关视图
@api_view(['POST'])
@permission_classes([IsAuthenticated])
def acknowledge_alert(request):
    """确认告警"""
    try:
        alert_id = request.data.get('alert_id')
        comment = request.data.get('comment', '')

        if not alert_id:
            return Response({
                'success': False,
                'message': '请指定告警ID'
            }, status=status.HTTP_400_BAD_REQUEST)

        try:
            alert = MonitoringAlert.objects.get(id=alert_id)
        except MonitoringAlert.DoesNotExist:
            return Response({
                'success': False,
                'message': '告警不存在'
            }, status=status.HTTP_404_NOT_FOUND)

        # 更新告警状态
        alert.status = 'acknowledged'
        alert.acknowledged_time = timezone.now()
        alert.acknowledged_by = request.user
        alert.acknowledgment_message = comment
        alert.save()

        return Response({
            'success': True,
            'message': '告警已确认',
            'data': {
                'id': alert.id,
                'status': alert.status,
                'acknowledged_time': alert.acknowledged_time.isoformat(),
                'acknowledged_by': alert.acknowledged_by.username
            }
        })

    except Exception as e:
        logger.error(f"确认告警失败: {e}")
        return Response({
            'success': False,
            'message': f'确认失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def resolve_alert(request):
    """解决告警"""
    try:
        alert_id = request.data.get('alert_id')
        comment = request.data.get('comment', '')

        if not alert_id:
            return Response({
                'success': False,
                'message': '请指定告警ID'
            }, status=status.HTTP_400_BAD_REQUEST)

        try:
            alert = MonitoringAlert.objects.get(id=alert_id)
        except MonitoringAlert.DoesNotExist:
            return Response({
                'success': False,
                'message': '告警不存在'
            }, status=status.HTTP_404_NOT_FOUND)

        # 更新告警状态
        alert.status = 'resolved'
        alert.resolved_time = timezone.now()
        if comment:
            alert.acknowledgment_message = comment
        alert.save()

        return Response({
            'success': True,
            'message': '告警已解决',
            'data': {
                'id': alert.id,
                'status': alert.status,
                'resolved_time': alert.resolved_time.isoformat()
            }
        })

    except Exception as e:
        logger.error(f"解决告警失败: {e}")
        return Response({
            'success': False,
            'message': f'解决失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['GET'])
@permission_classes([IsAuthenticated])
def test_simple_api(request):
    """简单测试API"""
    try:
        return Response({
            'success': True,
            'message': '简单测试成功',
            'data': {'test': 'value'}
        })
    except Exception as e:
        return Response({
            'success': False,
            'message': f'简单测试失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['GET'])
@permission_classes([IsAuthenticated])
def get_host_items(request):
    """获取主机监控项（支持分页）"""
    host_id = request.query_params.get('host_id')
    zabbix_server_id = request.query_params.get('zabbix_server_id')
    page = int(request.query_params.get('page', 1))
    page_size = int(request.query_params.get('page_size', 50))
    search = request.query_params.get('search', '')

    if not host_id:
        return Response({
            'success': False,
            'message': '缺少主机ID参数'
        }, status=status.HTTP_400_BAD_REQUEST)

    if not zabbix_server_id:
        return Response({
            'success': False,
            'message': '缺少Zabbix服务器ID参数'
        }, status=status.HTTP_400_BAD_REQUEST)

    try:
        # 获取Zabbix服务器配置
        try:
            zabbix_server = ZabbixServer.objects.get(id=zabbix_server_id)
        except ZabbixServer.DoesNotExist:
            return Response({
                'success': False,
                'message': '指定的Zabbix服务器不存在'
            }, status=status.HTTP_404_NOT_FOUND)

        # 获取Zabbix API管理器
        from .utils.zabbix_api import ZabbixAPIManager
        api_manager = ZabbixAPIManager(zabbix_server)
        if not api_manager._connect():
            return Response({
                'success': False,
                'message': 'Zabbix服务器连接失败'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        # 前端传递的host_id就是Zabbix主机ID，直接使用
        zabbix_host_id = host_id
        logger.info(f"开始获取主机 {zabbix_host_id} 的监控项")

        # 使用正确的 Zabbix API 获取指定主机的监控项
        # 获取所有监控项（包括启用和禁用的）
        all_items_raw = api_manager.zapi.item.get(
            output='extend',  # 获取完整信息
            hostids=[zabbix_host_id],  # 使用Zabbix主机ID，必须是列表格式
            selectHosts=['host', 'name'],  # 关联主机信息
            sortfield='name',
            sortorder='ASC'
        )

        logger.info(f"从Zabbix获取到主机 {zabbix_host_id} 的监控项: {len(all_items_raw)} 个")

        # 分类处理监控项
        all_items = []

        for item in all_items_raw:
            # 根据templateid判断来源
            if item.get('templateid') and item.get('templateid') != '0':
                # 有templateid说明是从模板继承的
                item['source'] = 'template'
                item['source_name'] = '模板继承'
                item['deletable'] = False  # 模板继承的不能删除
            else:
                # 没有templateid说明是主机自定义的
                item['source'] = 'host'
                item['source_name'] = '主机自定义'
                item['deletable'] = True  # 主机自定义的可以删除

            # 确保status字段是整数类型
            if 'status' in item:
                item['status'] = int(item['status'])

            all_items.append(item)

        # 统计数量
        host_items_count = len([item for item in all_items if item['source'] == 'host'])
        template_items_count = len([item for item in all_items if item['source'] == 'template'])

        logger.info(f"监控项分类统计: 主机自定义 {host_items_count} 个, 模板继承 {template_items_count} 个")

        # 如果有搜索条件，进行过滤
        if search:
            filtered_items = [
                item for item in all_items
                if search.lower() in item.get('name', '').lower() or
                   search.lower() in item.get('key_', '').lower()
            ]
        else:
            filtered_items = all_items

        total = len(filtered_items)

        # 手动分页
        start = (page - 1) * page_size
        end = start + page_size
        items = filtered_items[start:end]

        logger.info(f"获取到主机 {host_id} 的监控项: 第{page}页，{len(items)} 个，总计 {total} 个")

        return Response({
            'success': True,
            'data': {
                'items': items,
                'total': total,
                'page': page,
                'page_size': page_size,
                'total_pages': (total + page_size - 1) // page_size
            },
            'message': f'成功获取第{page}页监控项，共 {len(items)} 个'
        })

    except Exception as e:
        logger.error(f"获取主机监控项失败: {e}")
        return Response({
            'success': False,
            'message': f'获取主机监控项失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def update_item_status(request):
    """更新监控项状态"""
    item_id = request.data.get('item_id')
    status_value = request.data.get('status')
    zabbix_server_id = request.data.get('zabbix_server_id')

    if not item_id:
        return Response({
            'success': False,
            'message': '缺少监控项ID参数'
        }, status=status.HTTP_400_BAD_REQUEST)

    if status_value is None:
        return Response({
            'success': False,
            'message': '缺少状态参数'
        }, status=status.HTTP_400_BAD_REQUEST)

    if not zabbix_server_id:
        return Response({
            'success': False,
            'message': '缺少Zabbix服务器ID参数'
        }, status=status.HTTP_400_BAD_REQUEST)

    try:
        # 获取Zabbix服务器配置
        try:
            zabbix_server = ZabbixServer.objects.get(id=zabbix_server_id)
        except ZabbixServer.DoesNotExist:
            return Response({
                'success': False,
                'message': '指定的Zabbix服务器不存在'
            }, status=status.HTTP_404_NOT_FOUND)

        # 获取Zabbix API管理器
        from .utils.zabbix_api import ZabbixAPIManager
        api_manager = ZabbixAPIManager(zabbix_server)
        if not api_manager._connect():
            return Response({
                'success': False,
                'message': 'Zabbix服务器连接失败'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        # 更新监控项状态
        result = api_manager.zapi.item.update({
            'itemid': item_id,
            'status': status_value
        })

        logger.info(f"更新监控项 {item_id} 状态为 {status_value}: {result}")

        return Response({
            'success': True,
            'data': result,
            'message': f'监控项状态已更新为 {"启用" if status_value == 0 else "禁用"}'
        })

    except Exception as e:
        logger.error(f"更新监控项状态失败: {e}")
        return Response({
            'success': False,
            'message': f'更新监控项状态失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def delete_item(request):
    """删除监控项"""
    try:
        item_id = request.data.get('item_id')
        zabbix_server_id = request.data.get('zabbix_server_id')

        if not item_id:
            return Response({
                'success': False,
                'message': '缺少监控项ID'
            }, status=status.HTTP_400_BAD_REQUEST)

        # 获取API管理器
        api_manager = get_zabbix_api_manager(zabbix_server_id)
        if not api_manager:
            return Response({
                'success': False,
                'message': 'Zabbix服务器连接失败'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        # 删除监控项
        result = api_manager.zapi.item.delete([item_id])

        if result:
            logger.info(f"监控项 {item_id} 删除成功")
            return Response({
                'success': True,
                'message': '监控项删除成功'
            })
        else:
            return Response({
                'success': False,
                'message': '监控项删除失败'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    except Exception as e:
        logger.error(f"删除监控项失败: {str(e)}")
        return Response({
            'success': False,
            'message': f'删除监控项失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['GET'])
@permission_classes([IsAuthenticated])
def get_alert_workflow(request):
    """获取告警工作流状态"""
    try:
        alert_id = request.query_params.get('alert_id')

        if not alert_id:
            return Response({
                'success': False,
                'message': '请指定告警ID'
            }, status=status.HTTP_400_BAD_REQUEST)

        try:
            alert = MonitoringAlert.objects.get(id=alert_id)
        except MonitoringAlert.DoesNotExist:
            return Response({
                'success': False,
                'message': '告警不存在'
            }, status=status.HTTP_404_NOT_FOUND)

        # 获取工作流状态
        from .utils.alert_processor import alert_processor
        workflow_status = alert_processor.get_alert_workflow_status(alert)

        return Response({
            'success': True,
            'data': workflow_status
        })

    except Exception as e:
        logger.error(f"获取告警工作流失败: {e}")
        return Response({
            'success': False,
            'message': f'获取工作流失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def batch_alert_action(request):
    """批量告警操作"""
    try:
        alert_ids = request.data.get('alert_ids', [])
        action = request.data.get('action')  # acknowledge, resolve, suppress
        comment = request.data.get('comment', '')

        if not alert_ids:
            return Response({
                'success': False,
                'message': '请指定告警ID列表'
            }, status=status.HTTP_400_BAD_REQUEST)

        if action not in ['acknowledge', 'resolve', 'suppress']:
            return Response({
                'success': False,
                'message': '无效的操作类型'
            }, status=status.HTTP_400_BAD_REQUEST)

        # 获取告警
        alerts = MonitoringAlert.objects.filter(id__in=alert_ids)
        if not alerts.exists():
            return Response({
                'success': False,
                'message': '未找到指定的告警'
            }, status=status.HTTP_404_NOT_FOUND)

        success_count = 0
        failed_count = 0

        for alert in alerts:
            try:
                if action == 'acknowledge':
                    if alert.status == 'active':
                        alert.status = 'acknowledged'
                        alert.acknowledged_time = timezone.now()
                        alert.acknowledged_by = request.user
                        alert.acknowledgment_message = comment
                        alert.save()
                        success_count += 1
                elif action == 'resolve':
                    if alert.status in ['active', 'acknowledged']:
                        alert.status = 'resolved'
                        alert.resolved_time = timezone.now()
                        if comment:
                            alert.acknowledgment_message = comment
                        alert.save()
                        success_count += 1
                elif action == 'suppress':
                    if alert.status in ['active', 'acknowledged']:
                        alert.status = 'suppressed'
                        alert.save()
                        success_count += 1
            except Exception as e:
                logger.error(f"批量操作告警 {alert.id} 失败: {e}")
                failed_count += 1

        return Response({
            'success': True,
            'message': f'批量操作完成，成功: {success_count}, 失败: {failed_count}',
            'data': {
                'success_count': success_count,
                'failed_count': failed_count,
                'total_count': len(alert_ids)
            }
        })

    except Exception as e:
        logger.error(f"批量告警操作失败: {e}")
        return Response({
            'success': False,
            'message': f'批量操作失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['GET', 'POST'])
@permission_classes([IsAuthenticated])
def notification_rules(request):
    """通知规则管理"""
    if request.method == 'GET':
        try:
            # 获取通知规则配置
            rules = {
                'severity_rules': {
                    'disaster': {
                        'enabled': True,
                        'channels': ['email', 'dingtalk', 'wechat'],
                        'immediate': True,
                        'escalation_time': 5  # 分钟
                    },
                    'high': {
                        'enabled': True,
                        'channels': ['email', 'dingtalk'],
                        'immediate': True,
                        'escalation_time': 10
                    },
                    'average': {
                        'enabled': True,
                        'channels': ['email'],
                        'immediate': False,
                        'escalation_time': 20
                    },
                    'warning': {
                        'enabled': True,
                        'channels': ['email'],
                        'immediate': False,
                        'escalation_time': 30
                    },
                    'information': {
                        'enabled': False,
                        'channels': [],
                        'immediate': False,
                        'escalation_time': 60
                    }
                },
                'deduplication': {
                    'enabled': True,
                    'time_window': 5,  # 分钟
                    'same_host_only': True
                },
                'quiet_hours': {
                    'enabled': False,
                    'start_time': '22:00',
                    'end_time': '08:00',
                    'emergency_only': True  # 紧急告警仍然发送
                }
            }

            return Response({
                'success': True,
                'data': rules
            })

        except Exception as e:
            logger.error(f"获取通知规则失败: {e}")
            return Response({
                'success': False,
                'message': f'获取通知规则失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    elif request.method == 'POST':
        try:
            # 更新通知规则配置
            rules_data = request.data

            # 这里可以将规则保存到数据库或配置文件
            # 目前简化为返回成功

            return Response({
                'success': True,
                'message': '通知规则更新成功',
                'data': rules_data
            })

        except Exception as e:
            logger.error(f"更新通知规则失败: {e}")
            return Response({
                'success': False,
                'message': f'更新通知规则失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def retry_failed_notifications(request):
    """重试失败的通知"""
    try:
        from .utils.notification_service import NotificationService
        notification_service = NotificationService()

        # 重试失败的通知
        notification_service.retry_failed_notifications()

        return Response({
            'success': True,
            'message': '重试任务已启动'
        })

    except Exception as e:
        logger.error(f"重试失败通知失败: {e}")
        return Response({
            'success': False,
            'message': f'重试失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['GET'])
@permission_classes([IsAuthenticated])
def notification_statistics(request):
    """通知统计"""
    try:
        from datetime import timedelta

        # 获取最近24小时的通知统计
        last_24h = timezone.now() - timedelta(hours=24)

        # 按状态统计
        status_stats = AlertNotification.objects.filter(
            created_at__gte=last_24h
        ).values('status').annotate(count=Count('id'))

        # 按渠道统计
        channel_stats = AlertNotification.objects.filter(
            created_at__gte=last_24h
        ).values('channel__name', 'channel__channel_type').annotate(count=Count('id'))

        # 按小时统计
        hourly_stats = []
        for i in range(24):
            hour_start = timezone.now() - timedelta(hours=i+1)
            hour_end = timezone.now() - timedelta(hours=i)

            hour_count = AlertNotification.objects.filter(
                created_at__gte=hour_start,
                created_at__lt=hour_end
            ).count()

            hourly_stats.append({
                'hour': hour_start.strftime('%H:00'),
                'count': hour_count
            })

        return Response({
            'success': True,
            'data': {
                'status_stats': list(status_stats),
                'channel_stats': list(channel_stats),
                'hourly_stats': hourly_stats[::-1]  # 反转，最早的在前
            }
        })

    except Exception as e:
        logger.error(f"获取通知统计失败: {e}")
        return Response({
            'success': False,
            'message': f'获取统计失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['GET'])
@permission_classes([IsAuthenticated])
def get_monitoring_templates(request):
    """获取监控模板列表"""
    try:
        zabbix_server_id = request.query_params.get('zabbix_server_id')

        if not zabbix_server_id:
            return Response({'error': '缺少zabbix_server_id参数'}, status=400)

        zabbix_server = ZabbixServer.objects.get(id=zabbix_server_id)

        from .utils.zabbix_api import ZabbixAPIManager
        api_manager = ZabbixAPIManager(zabbix_server)

        if not api_manager._connect():
            return Response({'error': 'Zabbix API连接失败'}, status=500)

        # 获取所有模板
        templates = api_manager.zapi.template.get(
            output=['templateid', 'name', 'description'],
            sortfield='name'
        )

        return Response({
            'success': True,
            'data': templates
        })

    except ZabbixServer.DoesNotExist:
        return Response({'error': 'Zabbix服务器不存在'}, status=404)
    except Exception as e:
        logger.error(f"获取监控模板失败: {e}")
        return Response({'error': str(e)}, status=500)


@api_view(['GET'])
@permission_classes([IsAuthenticated])
def search_templates(request):
    """搜索监控模板"""
    try:
        zabbix_server_id = request.query_params.get('zabbix_server_id')
        search_query = request.query_params.get('search', '').strip()

        if not zabbix_server_id:
            return Response({'error': '缺少zabbix_server_id参数'}, status=400)

        if not search_query:
            return Response({
                'success': True,
                'data': [],
                'message': '请输入搜索关键词'
            })

        if len(search_query) < 2:
            return Response({
                'success': True,
                'data': [],
                'message': '搜索关键词至少需要2个字符'
            })

        zabbix_server = ZabbixServer.objects.get(id=zabbix_server_id)

        from .utils.zabbix_api import ZabbixAPIManager
        api_manager = ZabbixAPIManager(zabbix_server)

        if not api_manager._connect():
            return Response({'error': 'Zabbix API连接失败'}, status=500)

        # 获取所有模板，然后在Python中进行搜索过滤
        all_templates = api_manager.zapi.template.get(
            output=['templateid', 'name', 'description'],
            sortfield='name'
        )

        # 在Python中进行模糊搜索，优先显示主要模板
        search_lower = search_query.lower()
        templates = []
        priority_templates = []  # 优先级模板

        for template in all_templates:
            if (search_lower in template['name'].lower() or
                (template.get('description') and search_lower in template['description'].lower())):

                # 优先级模板：以"Template OS"开头的模板
                if template['name'].startswith('Template OS'):
                    priority_templates.append(template)
                else:
                    templates.append(template)

        # 合并结果，优先级模板在前
        final_templates = priority_templates + templates

        # 限制返回数量，提升性能
        if len(final_templates) > 20:
            final_templates = final_templates[:20]

        return Response({
            'success': True,
            'data': final_templates,
            'total': len(final_templates)
        })

    except ZabbixServer.DoesNotExist:
        return Response({'error': 'Zabbix服务器不存在'}, status=404)
    except Exception as e:
        logger.error(f"搜索模板失败: {e}")
        return Response({'error': str(e)}, status=500)


@api_view(['GET'])
@permission_classes([IsAuthenticated])
def get_template_items(request):
    """获取指定模板的监控项"""
    try:
        zabbix_server_id = request.query_params.get('zabbix_server_id')
        template_id = request.query_params.get('template_id')
        search_query = request.query_params.get('search', '').strip()

        if not zabbix_server_id:
            return Response({'error': '缺少zabbix_server_id参数'}, status=400)

        if not template_id:
            return Response({'error': '缺少template_id参数'}, status=400)

        zabbix_server = ZabbixServer.objects.get(id=zabbix_server_id)

        from .utils.zabbix_api import ZabbixAPIManager
        api_manager = ZabbixAPIManager(zabbix_server)

        if not api_manager._connect():
            return Response({'error': 'Zabbix API连接失败'}, status=500)

        # 构建查询参数
        params = {
            'output': ['itemid', 'name', 'key_', 'description', 'units', 'value_type', 'type', 'status', 'delay', 'lastvalue', 'lastclock'],
            'templateids': [template_id],
            'sortfield': 'name'
        }

        # 如果有搜索关键词，添加搜索条件
        if search_query:
            params['search'] = {'name': search_query}
            params['searchWildcardsEnabled'] = True

        # 获取模板的监控项
        items = api_manager.zapi.item.get(**params)

        # 获取模板信息
        template_info = api_manager.zapi.template.get(
            output=['templateid', 'name', 'description'],
            templateids=[template_id]
        )

        # 获取模板关联的主机
        template_hosts = []
        if template_info:
            hosts = api_manager.zapi.host.get(
                output=['hostid', 'name', 'host'],
                templateids=[template_id]
            )
            template_hosts = hosts

        # 构建返回的模板信息
        template_data = None
        if template_info:
            template_data = template_info[0]
            template_data['hosts'] = template_hosts

        return Response({
            'success': True,
            'data': {
                'template': template_data,
                'items': items,
                'total': len(items)
            }
        })

    except ZabbixServer.DoesNotExist:
        return Response({'error': 'Zabbix服务器不存在'}, status=404)
    except Exception as e:
        logger.error(f"获取模板监控项失败: {e}")
        return Response({'error': str(e)}, status=500)


# ==================== 新的SSE实时告警推送功能 ====================

@csrf_exempt
def alert_stream(request):
    """SSE告警流 - 安全版本"""
    from .sse_manager import sse_manager
    from rest_framework.authtoken.models import Token

    # 认证检查
    user = None
    token_key = request.GET.get('token') or request.META.get('HTTP_AUTHORIZATION', '').replace('Token ', '')

    if token_key:
        try:
            token = Token.objects.get(key=token_key)
            user = token.user
        except Token.DoesNotExist:
            pass

    if not user:
        return StreamingHttpResponse(
            iter(['event: error\ndata: {"error": "Authentication required"}\n\n']),
            content_type='text/event-stream',
            status=401
        )

    # 生成连接ID
    connection_id = str(uuid.uuid4())
    logger.info(f"用户 {user.id} 请求建立SSE连接: {connection_id}")

    def sse_generator():
        connection = None
        try:
            # 添加连接到管理器
            connection = sse_manager.add_connection(user.id, connection_id)

            # 发送连接确认
            yield f"event: connected\ndata: {json.dumps({'message': 'SSE连接已建立', 'user_id': user.id, 'connection_id': connection_id, 'timestamp': timezone.now().isoformat()})}\n\n"

            # 发送初始心跳
            yield f"event: heartbeat\ndata: {json.dumps({'timestamp': timezone.now().isoformat()})}\n\n"

            # 持续运行，保持长连接
            start_time = timezone.now()
            last_heartbeat = start_time
            heartbeat_interval = 30  # 30秒心跳间隔

            while True:  # 保持长连接
                current_time = timezone.now()

                # 检查连接是否仍然有效
                if not sse_manager.is_connection_active(user.id, connection_id):
                    logger.info(f"SSE连接 {connection_id} 已失效，退出生成器")
                    break

                # 处理消息队列中的消息
                if connection and hasattr(connection, 'message_queue'):
                    try:
                        # 非阻塞获取消息
                        while not connection.message_queue.empty():
                            try:
                                event_type, data = connection.message_queue.get_nowait()
                                yield f"event: {event_type}\ndata: {json.dumps(data, ensure_ascii=False)}\n\n"
                            except:
                                break
                    except Exception as e:
                        logger.error(f"处理SSE消息队列时出错: {e}")

                # 发送心跳
                if (current_time - last_heartbeat).total_seconds() >= heartbeat_interval:
                    yield f"event: heartbeat\ndata: {json.dumps({'timestamp': current_time.isoformat()})}\n\n"
                    last_heartbeat = current_time

                # 发送keepalive注释（每5秒）
                yield f": keepalive {current_time.isoformat()}\n\n"

                # 简单延时，减少频繁yield
                import time
                time.sleep(2)  # 2秒延时

        except GeneratorExit:
            logger.info(f"用户 {user.id} SSE连接正常关闭")
        except Exception as e:
            logger.error(f"SSE生成器异常: {e}")
        finally:
            # 清理连接
            if connection:
                sse_manager.remove_connection(user.id)

    response = StreamingHttpResponse(
        sse_generator(),
        content_type='text/event-stream'
    )
    response['Cache-Control'] = 'no-cache'
    # 移除Connection头，避免Django开发服务器错误
    # response['Connection'] = 'keep-alive'
    response['Access-Control-Allow-Origin'] = '*'
    response['Access-Control-Allow-Headers'] = 'Authorization'

    return response


@api_view(['GET'])
@permission_classes([IsAuthenticated])
def sse_status(request):
    """获取SSE连接状态"""
    from .sse_manager import sse_manager

    try:
        status_info = sse_manager.get_status()
        return Response({
            'success': True,
            'data': status_info,
            'message': 'SSE状态获取成功'
        })
    except Exception as e:
        logger.error(f"获取SSE状态失败: {e}")
        return Response({
            'success': False,
            'message': f'获取SSE状态失败: {str(e)}'
        }, status=500)


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def test_alert_push(request):
    """测试告警推送功能 - 增强版本，支持真实告警创建和通知渠道选择"""
    from .sse_manager import sse_manager
    from .utils.notification_service import NotificationService
    from .utils.alert_processor import AlertProcessor
    import uuid

    # 获取测试参数
    user_id = request.data.get('user_id', request.user.id)
    alert_type = request.data.get('alert_type', 'test')
    message = request.data.get('message', '这是一个SSE实时推送测试告警')
    severity = request.data.get('severity', 'warning')
    mode = request.data.get('mode', 'simple')  # 测试模式：simple, notification, full
    notification_channels = request.data.get('notification_channels', [])  # 指定通知渠道ID列表

    # 根据模式设置参数
    if mode == 'notification':
        create_real_alert = True  # 通知模式需要创建真实告警
        send_notifications = True  # 发送通知
        logger.info(f"通知模式: create_real_alert={create_real_alert}, send_notifications={send_notifications}")
    elif mode == 'full':
        create_real_alert = request.data.get('create_real_alert', True)
        send_notifications = request.data.get('send_notifications', True)
        logger.info(f"完整模式: create_real_alert={create_real_alert}, send_notifications={send_notifications}")
    else:  # simple 模式
        create_real_alert = request.data.get('create_real_alert', False)
        send_notifications = request.data.get('send_notifications', False)
        logger.info(f"简单模式: create_real_alert={create_real_alert}, send_notifications={send_notifications}")

    logger.info(f"测试推送参数: mode={mode}, user_id={user_id}, create_real_alert={create_real_alert}, send_notifications={send_notifications}")

    try:
        if create_real_alert:
            # 创建真实的告警记录
            from .models import MonitoringAlert, ZabbixServer
            from cmdb.models import Host

            # 获取默认的Zabbix服务器
            zabbix_server = ZabbixServer.objects.filter(is_active=True).first()
            if not zabbix_server:
                return Response({
                    'success': False,
                    'message': '没有找到活跃的Zabbix服务器'
                }, status=status.HTTP_400_BAD_REQUEST)

            # 获取一个测试主机（如果没有则创建虚拟主机信息）
            test_host = Host.objects.first()

            # 创建真实告警
            real_alert = MonitoringAlert.objects.create(
                title=f"[SSE测试] {message}",
                description=f"这是通过SSE测试接口创建的真实告警，用于测试实时推送和通知功能。时间：{timezone.now()}",
                host=test_host,
                zabbix_server=zabbix_server,
                zabbix_event_id=f"test_{uuid.uuid4().hex[:8]}",
                zabbix_trigger_id=f"trigger_{uuid.uuid4().hex[:8]}",
                severity=severity,
                status='active',
                event_time=timezone.now(),
                raw_data={
                    'source': 'sse_test',
                    'test_user': request.user.username,
                    'test_time': timezone.now().isoformat()
                }
            )

            # 准备SSE推送数据
            alert_data = {
                'id': real_alert.id,
                'title': real_alert.title,
                'hostname': real_alert.host.hostname if real_alert.host else "测试主机",
                'severity': real_alert.severity,
                'status': real_alert.status,
                'event_time': real_alert.event_time.isoformat(),
                'zabbix_server': real_alert.zabbix_server.name,
                'description': real_alert.description,
                'host_ip': real_alert.host.public_ip or real_alert.host.private_ip or real_alert.host.ip if real_alert.host else '192.168.1.100'
            }

            # 发送通知（如果指定了通知渠道）
            notification_results = []
            if send_notifications:
                try:
                    notification_service = NotificationService()

                    if notification_channels:
                        # 发送到指定的通知渠道
                        from .models import NotificationChannel
                        selected_channels = NotificationChannel.objects.filter(
                            id__in=notification_channels,
                            is_active=True
                        )

                        for channel in selected_channels:
                            try:
                                logger.info(f"开始发送通知到渠道: {channel.name}")
                                notification_service._send_single_notification(real_alert, channel)
                                notification_results.append({
                                    'channel': channel.name,
                                    'status': 'success',
                                    'message': '通知发送成功'
                                })
                                logger.info(f"通知发送成功到渠道: {channel.name}")
                            except Exception as e:
                                import traceback
                                logger.error(f"通知发送失败到渠道 {channel.name}: {e}")
                                logger.error(f"详细错误堆栈: {traceback.format_exc()}")
                                notification_results.append({
                                    'channel': channel.name,
                                    'status': 'failed',
                                    'message': str(e)
                                })
                    else:
                        # 发送到所有活跃的通知渠道
                        try:
                            notification_service.send_alert_notifications([real_alert])
                            notification_results.append({
                                'channel': 'all_active',
                                'status': 'success',
                                'message': '已发送到所有活跃通知渠道'
                            })
                        except Exception as e:
                            notification_results.append({
                                'channel': 'all_active',
                                'status': 'failed',
                                'message': str(e)
                            })
                except Exception as e:
                    import traceback
                    logger.error(f"通知服务整体失败: {e}")
                    logger.error(f"详细错误堆栈: {traceback.format_exc()}")
                    notification_results.append({
                        'channel': 'notification_service',
                        'status': 'failed',
                        'message': f'通知服务失败: {str(e)}'
                    })

            # SSE实时推送
            sse_success = sse_manager.broadcast_to_all('new_alert', alert_data)

            return Response({
                'success': True,
                'message': f'真实告警已创建并推送 (ID: {real_alert.id})',
                'data': {
                    'alert': alert_data,
                    'sse_pushed': sse_success,
                    'notifications_sent': send_notifications,
                    'notification_results': notification_results,
                    'alert_id': real_alert.id
                }
            })

        else:
            # 原有的简单测试推送（仅SSE，不创建告警记录）
            test_alert = {
                'id': f"test_{uuid.uuid4().hex[:8]}",
                'type': alert_type,
                'title': f"[SSE测试] {message}",
                'message': message,
                'severity': severity,
                'timestamp': timezone.now().isoformat(),
                'source': 'sse_test',
                'host': 'test-host',
                'item': 'test-item'
            }

            # 推送到指定用户或所有用户
            if user_id and user_id != 'all':
                success = sse_manager.broadcast_to_user(int(user_id), 'test_alert', test_alert)
                target = f'用户 {user_id}'
            else:
                sse_manager.broadcast_to_all('test_alert', test_alert)
                success = True
                target = '所有用户'

            return Response({
                'success': success,
                'message': f'测试告警已通过SSE推送给{target}',
                'data': {
                    'alert': test_alert,
                    'sse_pushed': success,
                    'notifications_sent': False,
                    'note': '这是简单测试推送，未创建真实告警记录'
                }
            })

    except Exception as e:
        logger.error(f"测试告警推送失败: {e}")
        return Response({
            'success': False,
            'message': f'测试告警推送失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class SSEConfigView(APIView):
    """SSE通知渠道配置视图"""
    permission_classes = [IsAuthenticated]

    def get(self, request):
        """获取用户的SSE通知渠道配置"""
        try:
            # 从用户配置中获取SSE通知渠道
            user_profile = getattr(request.user, 'profile', None)
            if user_profile and hasattr(user_profile, 'sse_notification_channels'):
                channel_ids = user_profile.sse_notification_channels
            else:
                # 如果没有用户配置，从session或默认配置获取
                channel_ids = request.session.get('sse_notification_channels', [])

            return Response({
                'success': True,
                'data': {
                    'notification_channels': channel_ids
                }
            })
        except Exception as e:
            logger.error(f"获取SSE配置失败: {str(e)}")
            return Response({
                'success': False,
                'message': f'获取SSE配置失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    def post(self, request):
        """保存用户的SSE通知渠道配置"""
        try:
            channel_ids = request.data.get('notification_channels', [])

            # 验证通知渠道是否存在
            if channel_ids:
                existing_channels = NotificationChannel.objects.filter(
                    id__in=channel_ids,
                    is_active=True
                ).values_list('id', flat=True)

                invalid_channels = set(channel_ids) - set(existing_channels)
                if invalid_channels:
                    return Response({
                        'success': False,
                        'message': f'无效的通知渠道ID: {list(invalid_channels)}'
                    }, status=status.HTTP_400_BAD_REQUEST)

            # 保存到session（简单实现）
            request.session['sse_notification_channels'] = channel_ids

            # 如果有用户配置模型，也可以保存到数据库
            # user_profile = getattr(request.user, 'profile', None)
            # if user_profile:
            #     user_profile.sse_notification_channels = channel_ids
            #     user_profile.save()

            logger.info(f"用户 {request.user.username} 保存SSE通知渠道配置: {channel_ids}")

            return Response({
                'success': True,
                'message': f'已配置 {len(channel_ids)} 个SSE通知渠道',
                'data': {
                    'notification_channels': channel_ids
                }
            })

        except Exception as e:
            logger.error(f"保存SSE配置失败: {str(e)}")
            return Response({
                'success': False,
                'message': f'保存SSE配置失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)








